mirror of
https://github.com/retro100/dosbox-wii.git
synced 2024-09-29 18:28:35 +02:00
DOSBox 0.62
This commit is contained in:
parent
a0ed243c23
commit
6a0c0c74c0
7
AUTHORS
7
AUTHORS
@ -1,9 +1,8 @@
|
|||||||
The DOSBox Team
|
The DOSBox Team
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
Sjoerd v.d. Berg <harekiet@zophar.net>
|
Sjoerd v.d. Berg <harekiet@users.sourceforge.net>
|
||||||
Peter Veenstra <qbix79@users.sourceforge.net>
|
Peter Veenstra <qbix79@users.sourceforge.net>
|
||||||
Felix Jakschitsch <yot@users.sourceforge.net>
|
|
||||||
Ulf Wohlers <finsterr@users.sourceforge.net>
|
Ulf Wohlers <finsterr@users.sourceforge.net>
|
||||||
Tommy Frössman <fanskapet@php-coders.net>
|
Tommy Frössman <fanskapet@sidvicious.se>
|
||||||
|
Dean Beeler <canadacow@users.sourceforge.net>
|
||||||
|
62
ChangeLog
62
ChangeLog
@ -1,3 +1,65 @@
|
|||||||
|
0.62
|
||||||
|
- Added blinking support in the shell and some color fixes.
|
||||||
|
- Fixed commandline parsing when .bat files involved (fixes -exit)
|
||||||
|
- Fixed issues with tabs in commandline not being processed correctly.
|
||||||
|
- Cleaned/improved shutdown sequence.
|
||||||
|
- Added some more bios functions (wait and delay functions).
|
||||||
|
- Made our XMS driver conform the specs better. (c2woody)
|
||||||
|
- Added support for some more ems functions.
|
||||||
|
- Added intelligent mpu401 emulation. (Srecko)
|
||||||
|
- Added soundblaster 16 emulation.
|
||||||
|
- Rewrote GUS emulation to sound more authentic.
|
||||||
|
- Improved pc speaker emulation.
|
||||||
|
- Added an internal (programmable) mixer.
|
||||||
|
- Added support a few soundblaster/adlib detection routines.
|
||||||
|
- Fixed lot's of bugs related to DMA transfers.
|
||||||
|
- Added interpolating prebuffering mixer routines.
|
||||||
|
- Added recording of OPL commands and raw midi.
|
||||||
|
- Fixed some bugs with the wave recording.
|
||||||
|
- Changed sensitivity settings of the mouse.
|
||||||
|
- Added ps2 mouse-emulation in bios interrupts (c2woody).
|
||||||
|
- Fixed some bugs with mouse emulation limits.
|
||||||
|
- Fixed a bug with an unterminated string in the drivelabel.
|
||||||
|
- Changed file search routines a bit to be more compatible.
|
||||||
|
- Added support for attribute-searching with fcb's.
|
||||||
|
- Added basic SDA.
|
||||||
|
- Added TPA and DIB.
|
||||||
|
- Added Lot's of missing dos tables (c2woody).
|
||||||
|
- Changed psp and dta functions to use dta.
|
||||||
|
- Returned filename in ds:dx in create-random-file (c2woody).
|
||||||
|
- Fixed a bug with date and time used on open files.
|
||||||
|
- Some mscdex fixes.
|
||||||
|
- Added the -version switch, which makes dosbox report its version.
|
||||||
|
- Added a keymapper.
|
||||||
|
- Added basic IPX emulation.
|
||||||
|
- Added cdrom iso support and floppy images support.
|
||||||
|
- Added the possibity to boot another dos version.
|
||||||
|
- Added Serial passthrough support (win32 only).
|
||||||
|
- Added the possibility to pause dosbox.
|
||||||
|
- Changed OpenGL so that it is initialized only when used.
|
||||||
|
- Make dosbox run at higher priority when active and lower when inactive.
|
||||||
|
- Added direct draw output support (win32 only).
|
||||||
|
- Added current running program to title bar.
|
||||||
|
- Rewrote video emulation to support new scalers.
|
||||||
|
- Added new graphics scalers like advmame3x,tv2x.
|
||||||
|
- Added a support for a few anti-debugger tricks.
|
||||||
|
- Improved the handling of the tab-key.
|
||||||
|
- Improved support for the numeric keyboard.
|
||||||
|
- Fixed a few cpu opcodes.
|
||||||
|
- Added cpu core simple (for lowerend machines)
|
||||||
|
- Fixed some nasty bugs in the dynamic cpu core.
|
||||||
|
- Added a few (rarely used) fpu opcodes.
|
||||||
|
- Fixed various issues with GCC 3.4.
|
||||||
|
- Many internal timer improvements (PIT and PIC).
|
||||||
|
- Added some more PIC commands (c2woody).
|
||||||
|
- Added BCD counting to the timers.
|
||||||
|
- Fix some vesa functions.
|
||||||
|
- Add some basic support for 132x25 and 132x45 textmodes.
|
||||||
|
- Improved Tandy emulation a lot.
|
||||||
|
- Lowered cpu usage when dosbox is idle.
|
||||||
|
- Allow virtualisation of some basic IO-ports (c2woody).
|
||||||
|
|
||||||
|
|
||||||
0.61
|
0.61
|
||||||
- Added a beta dynamic cpu for x86 hosts (very unstable)
|
- Added a beta dynamic cpu for x86 hosts (very unstable)
|
||||||
- Added opengl and hardware overlay display output
|
- Added opengl and hardware overlay display output
|
||||||
|
@ -3,5 +3,6 @@
|
|||||||
EXTRA_DIST = autogen.sh
|
EXTRA_DIST = autogen.sh
|
||||||
SUBDIRS = src include visualc docs visualc_net
|
SUBDIRS = src include visualc docs visualc_net
|
||||||
|
|
||||||
|
docdir = $(prefix)/share/doc/$(PACKAGE)
|
||||||
|
doc_DATA = README NEWS THANKS AUTHORS
|
||||||
|
|
||||||
|
39
Makefile.in
39
Makefile.in
@ -134,12 +134,17 @@ target_vendor = @target_vendor@
|
|||||||
|
|
||||||
EXTRA_DIST = autogen.sh
|
EXTRA_DIST = autogen.sh
|
||||||
SUBDIRS = src include visualc docs visualc_net
|
SUBDIRS = src include visualc docs visualc_net
|
||||||
|
|
||||||
|
docdir = $(prefix)/share/doc/$(PACKAGE)
|
||||||
|
doc_DATA = README NEWS THANKS AUTHORS
|
||||||
subdir = .
|
subdir = .
|
||||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||||
CONFIG_HEADER = config.h
|
CONFIG_HEADER = config.h
|
||||||
CONFIG_CLEAN_FILES =
|
CONFIG_CLEAN_FILES =
|
||||||
DIST_SOURCES =
|
DIST_SOURCES =
|
||||||
|
DATA = $(doc_DATA)
|
||||||
|
|
||||||
|
|
||||||
RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \
|
RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \
|
||||||
ps-recursive install-info-recursive uninstall-info-recursive \
|
ps-recursive install-info-recursive uninstall-info-recursive \
|
||||||
@ -189,6 +194,24 @@ $(srcdir)/config.h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4)
|
|||||||
distclean-hdr:
|
distclean-hdr:
|
||||||
-rm -f config.h stamp-h1
|
-rm -f config.h stamp-h1
|
||||||
uninstall-info-am:
|
uninstall-info-am:
|
||||||
|
docDATA_INSTALL = $(INSTALL_DATA)
|
||||||
|
install-docDATA: $(doc_DATA)
|
||||||
|
@$(NORMAL_INSTALL)
|
||||||
|
$(mkinstalldirs) $(DESTDIR)$(docdir)
|
||||||
|
@list='$(doc_DATA)'; for p in $$list; do \
|
||||||
|
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||||
|
f="`echo $$p | sed -e 's|^.*/||'`"; \
|
||||||
|
echo " $(docDATA_INSTALL) $$d$$p $(DESTDIR)$(docdir)/$$f"; \
|
||||||
|
$(docDATA_INSTALL) $$d$$p $(DESTDIR)$(docdir)/$$f; \
|
||||||
|
done
|
||||||
|
|
||||||
|
uninstall-docDATA:
|
||||||
|
@$(NORMAL_UNINSTALL)
|
||||||
|
@list='$(doc_DATA)'; for p in $$list; do \
|
||||||
|
f="`echo $$p | sed -e 's|^.*/||'`"; \
|
||||||
|
echo " rm -f $(DESTDIR)$(docdir)/$$f"; \
|
||||||
|
rm -f $(DESTDIR)$(docdir)/$$f; \
|
||||||
|
done
|
||||||
|
|
||||||
# This directory's subdirectories are mostly independent; you can cd
|
# This directory's subdirectories are mostly independent; you can cd
|
||||||
# into them and run `make' without going through this Makefile.
|
# into them and run `make' without going through this Makefile.
|
||||||
@ -446,9 +469,10 @@ distcleancheck: distclean
|
|||||||
exit 1; } >&2
|
exit 1; } >&2
|
||||||
check-am: all-am
|
check-am: all-am
|
||||||
check: check-recursive
|
check: check-recursive
|
||||||
all-am: Makefile config.h
|
all-am: Makefile $(DATA) config.h
|
||||||
installdirs: installdirs-recursive
|
installdirs: installdirs-recursive
|
||||||
installdirs-am:
|
installdirs-am:
|
||||||
|
$(mkinstalldirs) $(DESTDIR)$(docdir)
|
||||||
|
|
||||||
install: install-recursive
|
install: install-recursive
|
||||||
install-exec: install-exec-recursive
|
install-exec: install-exec-recursive
|
||||||
@ -491,7 +515,7 @@ info: info-recursive
|
|||||||
|
|
||||||
info-am:
|
info-am:
|
||||||
|
|
||||||
install-data-am:
|
install-data-am: install-docDATA
|
||||||
|
|
||||||
install-exec-am:
|
install-exec-am:
|
||||||
|
|
||||||
@ -519,7 +543,7 @@ ps: ps-recursive
|
|||||||
|
|
||||||
ps-am:
|
ps-am:
|
||||||
|
|
||||||
uninstall-am: uninstall-info-am
|
uninstall-am: uninstall-docDATA uninstall-info-am
|
||||||
|
|
||||||
uninstall-info: uninstall-info-recursive
|
uninstall-info: uninstall-info-recursive
|
||||||
|
|
||||||
@ -529,16 +553,17 @@ uninstall-info: uninstall-info-recursive
|
|||||||
distclean-hdr distclean-recursive distclean-tags distcleancheck \
|
distclean-hdr distclean-recursive distclean-tags distcleancheck \
|
||||||
distdir distuninstallcheck dvi dvi-am dvi-recursive info \
|
distdir distuninstallcheck dvi dvi-am dvi-recursive info \
|
||||||
info-am info-recursive install install-am install-data \
|
info-am info-recursive install install-am install-data \
|
||||||
install-data-am install-data-recursive install-exec \
|
install-data-am install-data-recursive install-docDATA \
|
||||||
install-exec-am install-exec-recursive install-info \
|
install-exec install-exec-am install-exec-recursive \
|
||||||
install-info-am install-info-recursive install-man \
|
install-info install-info-am install-info-recursive install-man \
|
||||||
install-recursive install-strip installcheck installcheck-am \
|
install-recursive install-strip installcheck installcheck-am \
|
||||||
installdirs installdirs-am installdirs-recursive \
|
installdirs installdirs-am installdirs-recursive \
|
||||||
maintainer-clean maintainer-clean-generic \
|
maintainer-clean maintainer-clean-generic \
|
||||||
maintainer-clean-recursive mostlyclean mostlyclean-generic \
|
maintainer-clean-recursive mostlyclean mostlyclean-generic \
|
||||||
mostlyclean-recursive pdf pdf-am pdf-recursive ps ps-am \
|
mostlyclean-recursive pdf pdf-am pdf-recursive ps ps-am \
|
||||||
ps-recursive tags tags-recursive uninstall uninstall-am \
|
ps-recursive tags tags-recursive uninstall uninstall-am \
|
||||||
uninstall-info-am uninstall-info-recursive uninstall-recursive
|
uninstall-docDATA uninstall-info-am uninstall-info-recursive \
|
||||||
|
uninstall-recursive
|
||||||
|
|
||||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||||
|
61
NEWS
61
NEWS
@ -1,3 +1,64 @@
|
|||||||
|
0.62
|
||||||
|
- Added blinking support in the shell and some color fixes.
|
||||||
|
- Fixed commandline parsing when .bat files involved (fixes -exit)
|
||||||
|
- Fixed issues with tabs in commandline not being processed correctly.
|
||||||
|
- Cleaned/improved shutdown sequence.
|
||||||
|
- Added some more bios functions (wait and delay functions).
|
||||||
|
- Made our XMS driver conform the specs better. (c2woody)
|
||||||
|
- Added support for some more ems functions.
|
||||||
|
- Added intelligent mpu401 emulation. (Srecko)
|
||||||
|
- Added soundblaster 16 emulation.
|
||||||
|
- Rewrote GUS emulation to sound more authentic.
|
||||||
|
- Improved pc speaker emulation.
|
||||||
|
- Added an internal (programmable) mixer.
|
||||||
|
- Added support a few soundblaster/adlib detection routines.
|
||||||
|
- Fixed lot's of bugs related to DMA transfers.
|
||||||
|
- Added interpolating prebuffering mixer routines.
|
||||||
|
- Added recording of OPL commands and raw midi.
|
||||||
|
- Fixed some bugs with the wave recording.
|
||||||
|
- Changed sensitivity settings of the mouse.
|
||||||
|
- Added ps2 mouse-emulation in bios interrupts (c2woody).
|
||||||
|
- Fixed some bugs with mouse emulation limits.
|
||||||
|
- Fixed a bug with an unterminated string in the drivelabel.
|
||||||
|
- Changed file search routines a bit to be more compatible.
|
||||||
|
- Added support for attribute-searching with fcb's.
|
||||||
|
- Added basic SDA.
|
||||||
|
- Added TPA and DIB.
|
||||||
|
- Added Lot's of missing dos tables (c2woody).
|
||||||
|
- Changed psp and dta functions to use dta.
|
||||||
|
- Returned filename in ds:dx in create-random-file (c2woody).
|
||||||
|
- Fixed a bug with date and time used on open files.
|
||||||
|
- Some mscdex fixes.
|
||||||
|
- Added the -version switch, which makes dosbox report its version.
|
||||||
|
- Added a keymapper.
|
||||||
|
- Added basic IPX emulation.
|
||||||
|
- Added cdrom iso support and floppy images support.
|
||||||
|
- Added the possibity to boot another dos version.
|
||||||
|
- Added Serial passthrough support (win32 only).
|
||||||
|
- Added the possibility to pause dosbox.
|
||||||
|
- Changed OpenGL so that it is initialized only when used.
|
||||||
|
- Make dosbox run at higher priority when active and lower when inactive.
|
||||||
|
- Added direct draw output support (win32 only).
|
||||||
|
- Added current running program to title bar.
|
||||||
|
- Rewrote video emulation to support new scalers.
|
||||||
|
- Added new graphics scalers like advmame3x,tv2x.
|
||||||
|
- Added a support for a few anti-debugger tricks.
|
||||||
|
- Improved the handling of the tab-key.
|
||||||
|
- Improved support for the numeric keyboard.
|
||||||
|
- Fixed a few cpu opcodes.
|
||||||
|
- Added cpu core simple (for lowerend machines)
|
||||||
|
- Fixed some nasty bugs in the dynamic cpu core.
|
||||||
|
- Added a few (rarely used) fpu opcodes.
|
||||||
|
- Fixed various issues with GCC 3.4.
|
||||||
|
- Many internal timer improvements (PIT and PIC).
|
||||||
|
- Added some more PIC commands (c2woody).
|
||||||
|
- Added BCD counting to the timers.
|
||||||
|
- Fix some vesa functions.
|
||||||
|
- Add some basic support for 132x25 and 132x45 textmodes.
|
||||||
|
- Improved Tandy emulation a lot.
|
||||||
|
- Lowered cpu usage when dosbox is idle.
|
||||||
|
- Allow virtualisation of some basic IO-ports (c2woody).
|
||||||
|
|
||||||
0.61
|
0.61
|
||||||
- Added a beta dynamic cpu for x86 hosts (very unstable)
|
- Added a beta dynamic cpu for x86 hosts (very unstable)
|
||||||
- Added opengl and hardware overlay display output
|
- Added opengl and hardware overlay display output
|
||||||
|
595
README
595
README
@ -1,4 +1,5 @@
|
|||||||
DOSBox v0.61
|
DOSBox v0.62
|
||||||
|
|
||||||
|
|
||||||
=====
|
=====
|
||||||
NOTE:
|
NOTE:
|
||||||
@ -6,7 +7,7 @@ NOTE:
|
|||||||
|
|
||||||
While we hope that, one day, DOSBox will run virtually all programs
|
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-
|
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
|
end machine will roughly be the equivalent of a 486 PC. The 0.60
|
||||||
release has added support for "protected mode" allowing for more complex and
|
release has added support for "protected mode" allowing for more complex and
|
||||||
recent programs, but note that this support is early in development 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
|
nowhere near as complete as the support for 386 real-mode games (or
|
||||||
@ -14,12 +15,180 @@ earlier). Also note that "protected mode" games need substantially more
|
|||||||
resources and may require a much faster processor for you to run it properly
|
resources and may require a much faster processor for you to run it properly
|
||||||
in DOSBox.
|
in DOSBox.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
======
|
======
|
||||||
Usage:
|
INDEX:
|
||||||
======
|
======
|
||||||
|
1. Quickstart
|
||||||
|
2. FAQ
|
||||||
|
3. Usage
|
||||||
|
4. Internal Programs
|
||||||
|
5. Special Keys
|
||||||
|
6. Keymapper
|
||||||
|
7. System Requirements
|
||||||
|
8. To run resource-demanding games
|
||||||
|
9. The config file
|
||||||
|
10. The language file
|
||||||
|
11. Building your own version of DOSBox
|
||||||
|
12. Special thanks
|
||||||
|
13. Contact
|
||||||
|
|
||||||
|
|
||||||
|
==============
|
||||||
|
1. Quickstart:
|
||||||
|
==============
|
||||||
|
|
||||||
|
Type INTRO in DOSBox. That's it.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
=======
|
||||||
|
2. FAQ:
|
||||||
|
=======
|
||||||
|
|
||||||
|
Some Frequently Asked Questions:
|
||||||
|
|
||||||
|
Q: I've got a Z instead of a C at the prompt.
|
||||||
|
Q: My CD-ROM doesn't work.
|
||||||
|
Q: The mouse doesn't work.
|
||||||
|
Q: The sound stutters.
|
||||||
|
Q: I can't type \ or : in DOSBox.
|
||||||
|
Q: The game/application can't find its CD-ROM.
|
||||||
|
Q: The game/application runs much too slow!
|
||||||
|
Q: I would like to change the memory size/cpu speed/ems/soundblaster IRQ.
|
||||||
|
Q: What sound hardware does DOSBox presently emulate?
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Q: I've got a Z instead of a C at the prompt.
|
||||||
|
A: You have to make your directories available as drives in DOSBox by using
|
||||||
|
the "mount" command. For example, in Windows "mount C D:\" would give
|
||||||
|
you a C in DOSBox which points at your Windows D:\ drive.
|
||||||
|
In Linux, "mount c /home/username" would give you a C in DOSBox
|
||||||
|
which points at /home/username in Linux.
|
||||||
|
|
||||||
|
|
||||||
|
Q: My CD-ROM doesn't work.
|
||||||
|
A: To mount your cdrom in DOSBox you have to specify some additional options
|
||||||
|
when mounting the cdrom.
|
||||||
|
To enable the most basic cdrom support:
|
||||||
|
- mount d f:\ -t cdrom
|
||||||
|
To enable low-level SDL-support:
|
||||||
|
- mount d f:\ -t cdrom -usecd 0
|
||||||
|
To enable low-level ioctl-support(win2k/xp/linux):
|
||||||
|
- mount d f:\ -t cdrom -usecd 0 -ioctl
|
||||||
|
To enable low-level aspi-support (win98 with aspi-layer installed):
|
||||||
|
- mount d f:\ -t cdrom -usecd 0 -apsi
|
||||||
|
|
||||||
|
In the commands: - d driveletter you in DOSBox
|
||||||
|
- f:\ location of cdrom on your PC.
|
||||||
|
- 0 The number of the cdrom drive, reported by mount -cd
|
||||||
|
See also the question: The game/application can't find its CD-ROM.
|
||||||
|
|
||||||
|
|
||||||
|
Q: The mouse doesn't work.
|
||||||
|
A: Normally DOSBox detects the mouse being used by a game. If you click on
|
||||||
|
the screen then it should get locked and work.
|
||||||
|
Sometimes the DOSBox mouse detection doesn't work with certain games. You
|
||||||
|
might have to force to lock the mouse then with ctrl-F10.
|
||||||
|
|
||||||
|
|
||||||
|
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.
|
||||||
|
You can also increase the prebuffer in the configfile
|
||||||
|
|
||||||
|
|
||||||
|
Q: I can't type \ or : 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 to dosbox.conf
|
||||||
|
4. Start the keymapper (CTRL-F1 or add -startmapper switch to dosbox)
|
||||||
|
5. for \ try the keys around "enter". For ":" try shift and the keys between
|
||||||
|
"enter" and "l" (US keyboard layout).
|
||||||
|
6. Use keyb.com for FreeDOS (http://projects.freedos.net/keyb/).
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
correct label (-label LABEL). To enable more low-level CD-ROM 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 .
|
||||||
|
Start 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. 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 read the remainder of this README and/or check
|
||||||
|
the site/forum:
|
||||||
|
http://dosbox.sourceforge.net
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
=========
|
||||||
|
3. Usage:
|
||||||
|
=========
|
||||||
|
|
||||||
|
An overview of the commandline options you can give to DOSBox:
|
||||||
|
|
||||||
dosbox [name] [-exit] [-c command] [-fullscreen] [-conf congfigfile]
|
dosbox [name] [-exit] [-c command] [-fullscreen] [-conf congfigfile]
|
||||||
[-lang languagefile] [-machine machinetype] [-noconsole]
|
[-lang languagefile] [-machine machinetype] [-noconsole]
|
||||||
|
[-startmapper]
|
||||||
|
|
||||||
|
dosbox -version
|
||||||
|
|
||||||
name
|
name
|
||||||
If "name" is a directory it'll mount that as the C: drive.
|
If "name" is a directory it'll mount that as the C: drive.
|
||||||
@ -43,13 +212,19 @@ dosbox [name] [-exit] [-c command] [-fullscreen] [-conf congfigfile]
|
|||||||
Start dosbox using the language string specified in "languagefile".
|
Start dosbox using the language string specified in "languagefile".
|
||||||
|
|
||||||
-noconsole (Windows Only)
|
-noconsole (Windows Only)
|
||||||
Start dosbox without showing the console window, output will
|
Start dosbox without showing the console window. Output will
|
||||||
be redirected to stdout.txt and stderr.txt
|
be redirected to stdout.txt and stderr.txt
|
||||||
|
|
||||||
-machine machinetype
|
-machine machinetype
|
||||||
Setup dosbox to emulate a specific type of machine. Valid choices are:
|
Setup dosbox to emulate a specific type of machine. Valid choices are:
|
||||||
auto,hercules,cga,tandy,vga.
|
hercules, cga, tandy, vga (default).
|
||||||
|
|
||||||
|
-startmapper
|
||||||
|
Enter the keymapper directly on startup. Useful for people with
|
||||||
|
keyboard problems.
|
||||||
|
|
||||||
|
-version
|
||||||
|
output version information and exit. Useful for frontends.
|
||||||
|
|
||||||
Note: If a name/command/configfile/languagefile contains a space in it, put
|
Note: If a name/command/configfile/languagefile contains a space in it, put
|
||||||
the whole name/command/configfile/languagefile between quotes("example").
|
the whole name/command/configfile/languagefile between quotes("example").
|
||||||
@ -64,16 +239,16 @@ In Windows you can also drag directories/files onto the dosbox executable.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
==================
|
=====================
|
||||||
Internal Programs:
|
4. 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:
|
In addition, the following commands are available:
|
||||||
|
|
||||||
MOUNT "Emulated Drive letter" "Real Drive or Directory"
|
MOUNT "Emulated Drive letter" "Real Drive or Directory"
|
||||||
[-t type] [-aspi] [-ioctl] [-usecd number] [-size drivesize]
|
[-t type] [-aspi] [-ioctl] [-usecd number] [-size drivesize]
|
||||||
[-label drivelabel]
|
[-label drivelabel] [-freesize sizemb]
|
||||||
MOUNT -cd
|
MOUNT -cd
|
||||||
|
|
||||||
Program to mount local directories as drives inside DOSBox.
|
Program to mount local directories as drives inside DOSBox.
|
||||||
@ -93,6 +268,10 @@ MOUNT -cd
|
|||||||
-size drivesize
|
-size drivesize
|
||||||
Sets the size of the drive.
|
Sets the size of the drive.
|
||||||
|
|
||||||
|
-freesize sizemb
|
||||||
|
Sets the amount of free space available on a drive in MB's. This
|
||||||
|
is a more simple version of -size.
|
||||||
|
|
||||||
-label drivelabel
|
-label drivelabel
|
||||||
Sets the name of the drive to "drivelabel". Needed on some
|
Sets the name of the drive to "drivelabel". Needed on some
|
||||||
systems if the cd label isn't read correctly. Useful when a
|
systems if the cd label isn't read correctly. Useful when a
|
||||||
@ -104,7 +283,7 @@ MOUNT -cd
|
|||||||
|
|
||||||
-ioctl
|
-ioctl
|
||||||
Forces to use ioctl commands. Only valid if mounting a cdrom under
|
Forces to use ioctl commands. Only valid if mounting a cdrom under
|
||||||
windows which support them (Win2000/XP/NT).
|
a Windows OS which support them (Win2000/XP/NT).
|
||||||
|
|
||||||
-usecd number
|
-usecd number
|
||||||
Forces to use SDL cdrom support for drive number.
|
Forces to use SDL cdrom support for drive number.
|
||||||
@ -118,11 +297,11 @@ MOUNT -cd
|
|||||||
|
|
||||||
Basically, MOUNT allows you to connect real hardware to DOSBox's "emulated"
|
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
|
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
|
DOSBox. It also allows you to change the drive's letter identification for
|
||||||
programs that demand specific drive letters.
|
programs that demand specific drive letters.
|
||||||
|
|
||||||
For example: Touche: Adventures of The Fifth Musketeer must be run on your C:
|
For example: Touche: Adventures of The Fifth Musketeer must be run on your C:
|
||||||
drive. Using DOSBox and it's mount command, you can trick into thinking it
|
drive. Using DOSBox and its mount command, you can trick into thinking it
|
||||||
is on C drive while placing it where you want it. For example, if the game
|
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
|
were in D:\TOUCHE, you can use the command MOUNT C D:\ would allow you to
|
||||||
run Touche from the D drive.
|
run Touche from the D drive.
|
||||||
@ -131,14 +310,16 @@ MOUNT -cd
|
|||||||
General MOUNT Examples:
|
General MOUNT Examples:
|
||||||
1. To mount c:\floppy as a floppy :
|
1. To mount c:\floppy as a floppy :
|
||||||
mount a c:\floppy -t floppy
|
mount a c:\floppy -t floppy
|
||||||
2. To mount system cdrom drive E as cdrom drive D in dosbox:
|
2. To mount system cdrom drive E as cdrom drive D in DOSBox:
|
||||||
mount d e:\ -t cdrom
|
mount d e:\ -t cdrom
|
||||||
3. To mount system cdrom drive at mountpoint /media/cdrom as cdrom drive D
|
3. To mount system cdrom drive at mountpoint /media/cdrom as cdrom drive D
|
||||||
in dosbox:
|
in dosbox:
|
||||||
mount d /media/cdrom -t cdrom -usecd 0
|
mount d /media/cdrom -t cdrom -usecd 0
|
||||||
4. To mount a drive with 870 mb free diskspace (rarely needed! experts only):
|
4. To mount a drive with 870 mb free diskspace (simple version):
|
||||||
|
mount c d:\ -freesize 870
|
||||||
|
5. To mount a drive with 870 mb free diskspace (experts only, full control):
|
||||||
mount c d:\ -size 4025,127,16513,1700
|
mount c d:\ -size 4025,127,16513,1700
|
||||||
5. To mount /home/dos/dosgames as drive C in DOSBox:
|
6. To mount /home/dos/dosgames as drive C in DOSBox:
|
||||||
mount c /home/dos/dosgames
|
mount c /home/dos/dosgames
|
||||||
|
|
||||||
MEM
|
MEM
|
||||||
@ -173,17 +354,192 @@ Examples:
|
|||||||
3. To free previous allocated memory :
|
3. To free previous allocated memory :
|
||||||
loadfix -f
|
loadfix -f
|
||||||
|
|
||||||
|
|
||||||
|
RESCAN
|
||||||
|
Make DOSBox reread the directory structure. Useful if you changed something
|
||||||
|
on a mounted drive outside of DOSBox.
|
||||||
|
|
||||||
|
|
||||||
|
MIXER
|
||||||
|
Makes DOSBox display its current volume settings.
|
||||||
|
You can change this way:
|
||||||
|
|
||||||
|
mixer channel left:right [/NOSHOW]
|
||||||
|
|
||||||
|
channel
|
||||||
|
Can be one of the following: MASTER, DISNEY, SPKR, GUS, SB, FM.
|
||||||
|
|
||||||
|
left:right
|
||||||
|
The volume levels in percentages. If you put a D in front it will be
|
||||||
|
in deciBell (example mixer gus d-10).
|
||||||
|
|
||||||
|
/NOSHOW
|
||||||
|
Prevents DOSBox from showing the result if you set one
|
||||||
|
of the volume levels.
|
||||||
|
|
||||||
|
|
||||||
|
IMGMOUNT
|
||||||
|
A utility to mount disk images and CD-ROM images in DOSBox.
|
||||||
|
|
||||||
|
IMGMOUNT DRIVE [imagefile] -t [image_type] -fs [image_format]
|
||||||
|
-size [sectorsbytesize, sectorsperhead, heads, cylinders]
|
||||||
|
|
||||||
|
imagefile
|
||||||
|
location of the image files to mount in DOSBox. Path is relative to
|
||||||
|
a mount point already inside DOSBox. CD-ROM images can be mounted
|
||||||
|
directly as well (path on the host).
|
||||||
|
|
||||||
|
-t
|
||||||
|
The following are valid image types:
|
||||||
|
floppy: Specifies a floppy image or images. DOSBox will automatically
|
||||||
|
identify the disk geometry ( 360K, 1.2MB, 720K, 1.44MB, etc).
|
||||||
|
iso: Specifies a CD-ROM iso image. The geometry is automatic and
|
||||||
|
set for this size. This can be an iso or a cue/bin.
|
||||||
|
hdd: Specifies a harddrive image. The proper CHS geometry
|
||||||
|
must be set for this to work.
|
||||||
|
|
||||||
|
-fs
|
||||||
|
The following are valid file system formats:
|
||||||
|
iso: Specifies the ISO 9660 CD-ROM format.
|
||||||
|
fat: Specifies the image uses the FAT file system. DOSBox will attempt
|
||||||
|
to mount this image as a drive in DOSBox and make the files
|
||||||
|
available from inside DOSBox.
|
||||||
|
none: DOSBox will make no attempt to read the file system on the disk.
|
||||||
|
This is useful if one needs to format it or one wants to boot
|
||||||
|
off of the disk using the BOOT command. When using the "none"
|
||||||
|
filesystem, one must specify the drive number (2 or 3,
|
||||||
|
where 2 = master, 3 = slave) rather than a drive letter.
|
||||||
|
For example, to mount a 70MB image as the slave drive device,
|
||||||
|
one would type:
|
||||||
|
"imgmount 3 d:\test.img -size 512,63,16,142 -fs none"
|
||||||
|
(without the quotes) Compare this with a mount to read the
|
||||||
|
drive in DOSBox, which would read as:
|
||||||
|
"imgmount e: d:\test.img -size 512,63,16,142"
|
||||||
|
|
||||||
|
-size
|
||||||
|
The Cylinders, Heads and Sectors specification of the drive.
|
||||||
|
Required to mount hard drive images.
|
||||||
|
|
||||||
|
An example of CD-ROM images:
|
||||||
|
1a. mount c /tmp
|
||||||
|
1b. imgmount d c:\myiso.iso -t iso
|
||||||
|
or (which also works):
|
||||||
|
2. imgmount d /tmp/myiso.iso -t iso
|
||||||
|
|
||||||
|
|
||||||
|
BOOT
|
||||||
|
Boot will start floppy images or hard disk images independent of the
|
||||||
|
operating system emulation offered by DOSBox. This will allow you to play
|
||||||
|
booter floppies or boot to other operating systems inside DOSBox.
|
||||||
|
|
||||||
|
BOOT [diskimg1.img diskimg2.img .. diskimgN.img] [-l driveletter]
|
||||||
|
|
||||||
|
diskimgN.img
|
||||||
|
This can be any number of floppy disk images one wants mounted after
|
||||||
|
DOSBox boots the specified drive letter.
|
||||||
|
To swap between images, one hits CTRL+F4 to swap out the current disk
|
||||||
|
and swap in the next disk in the list. Once the last disk in the list is
|
||||||
|
swapped out, the list loops back to the beginning.
|
||||||
|
|
||||||
|
[-l driveletter]
|
||||||
|
This parameter allows one to specify the drive to boot from.
|
||||||
|
The default is the A drive, the floppy drive. One can also boot off of
|
||||||
|
a hard drive image mounted as master by specifying "-l C"
|
||||||
|
without the quotes, or the drive as slave by specifying "-l D"
|
||||||
|
|
||||||
|
|
||||||
|
IPX
|
||||||
|
|
||||||
|
You need to enable IPX networking in the configuration file of DOSBox.
|
||||||
|
|
||||||
|
All of the IPX networking is managed through the internal DOSBox program
|
||||||
|
IPXNET. For help on the IPX networking from inside DOSBox, type
|
||||||
|
"IPXNET HELP" (without quotes) and the program will list out the commands
|
||||||
|
and relevant documentation.
|
||||||
|
|
||||||
|
With regard to actually setting up a network, one system needs to be
|
||||||
|
the server. To set this up, in a DOSBox session, one should type
|
||||||
|
"IPXNET STARTSERVER" (without the quotes). The server DOSBox session will
|
||||||
|
automatically add itself to the virtual IPX network. In turn, for every
|
||||||
|
other computer that should be part of the virtual IPX network,
|
||||||
|
you'll need to type "IPXNET CONNECT <computer host name or IP>".
|
||||||
|
For example, if your server is at bob.dosbox.com,
|
||||||
|
you would type "IPXNET CONNECT bob.dosbox.com" on every non-server system.
|
||||||
|
|
||||||
|
The following is an IPXNET command reference:
|
||||||
|
|
||||||
|
IPXNET CONNECT
|
||||||
|
|
||||||
|
IPXNET CONNECT opens a connection to an IPX tunneling server
|
||||||
|
running on another DOSBox session. The "address" parameter specifies
|
||||||
|
the IP address or host name of the server computer. One can also
|
||||||
|
specify the UDP port to use. By default IPXNET uses port 213, the
|
||||||
|
assigned IANA port for IPX tunneling, for its connection.
|
||||||
|
|
||||||
|
The syntax for IPXNET CONNECT is:
|
||||||
|
IPXNET CONNECT address <port>
|
||||||
|
|
||||||
|
IPXNET DISCONNECT
|
||||||
|
|
||||||
|
IPXNET DISCONNECT closes the connection to the IPX tunneling server.
|
||||||
|
|
||||||
|
The syntax for IPXNET DISCONNECT is:
|
||||||
|
IPXNET DISCONNECT
|
||||||
|
|
||||||
|
IPXNET STARTSERVER
|
||||||
|
|
||||||
|
IPXNET STARTSERVER starts and IPX tunneling server on this DOSBox
|
||||||
|
session. By default, the server will accept connections on UDP port
|
||||||
|
213, though this can be changed. Once the server is started, DOSBox
|
||||||
|
will automatically start a client connection to the IPX tunneling server.
|
||||||
|
|
||||||
|
The syntax for IPXNET STARTSERVER is:
|
||||||
|
IPXNET STARTSERVER <port>
|
||||||
|
|
||||||
|
IPXNET STOPSERVER
|
||||||
|
|
||||||
|
IPXNET STOPSERVER stops the IPX tunneling server running on this DOSBox
|
||||||
|
session. Care should be taken to ensure that all other connections have
|
||||||
|
terminated as well since stopping the server may cause lockups on other
|
||||||
|
machines still using the IPX tunneling server.
|
||||||
|
|
||||||
|
The syntax for IPXNET STOPSERVER is:
|
||||||
|
IPXNET STOPSERVER
|
||||||
|
|
||||||
|
IPXNET PING
|
||||||
|
|
||||||
|
IPXNET PING broadcasts a ping request through the IPX tunneled network.
|
||||||
|
In response, all other connected computers will respond to the ping
|
||||||
|
and report the time it took to receive and send the ping message.
|
||||||
|
|
||||||
|
The syntax for IPXNET PING is:
|
||||||
|
IPXNET PING
|
||||||
|
|
||||||
|
IPXNET STATUS
|
||||||
|
|
||||||
|
IPXNET STATUS reports the current state of this DOSBox's sessions
|
||||||
|
IPX tunneling network. For a list of the computers connected to the
|
||||||
|
network use the IPXNET PING command.
|
||||||
|
|
||||||
|
The syntax for IPXNET STATUS is:
|
||||||
|
IPXNET STATUS
|
||||||
|
|
||||||
For more information use the /? command line switch with the programs.
|
For more information use the /? command line switch with the programs.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
=============
|
|
||||||
Special Keys:
|
================
|
||||||
=============
|
5. Special Keys:
|
||||||
|
================
|
||||||
|
|
||||||
ALT-ENTER Go full screen and back.
|
ALT-ENTER Go full screen and back.
|
||||||
|
CTRL-F1 Start the keymapper.
|
||||||
|
CTRL-F4 Swap mounted disk-image (Only used with imgmount).
|
||||||
CTRL-F5 Save a screenshot.
|
CTRL-F5 Save a screenshot.
|
||||||
CTRL-F6 Start/Stop recording sound output to a wave file.
|
CTRL-F6 Start/Stop recording sound output to a wave file.
|
||||||
|
CTRL-ALT-F7 Start/Stop recording of OPL commands.
|
||||||
|
CTRL-ALT-F8 Start/Stop the recording of raw MIDI commands.
|
||||||
CTRL-F7 Decrease frameskip.
|
CTRL-F7 Decrease frameskip.
|
||||||
CTRL-F8 Increase frameskip.
|
CTRL-F8 Increase frameskip.
|
||||||
CTRL-F9 Kill dosbox.
|
CTRL-F9 Kill dosbox.
|
||||||
@ -191,13 +547,79 @@ CTRL-F10 Capture/Release the mouse.
|
|||||||
CTRL-F11 Slow down emulation (Decrease DOSBox Cycles).
|
CTRL-F11 Slow down emulation (Decrease DOSBox Cycles).
|
||||||
CTRL-F12 Speed up emulation (Increase DOSox Cycles).
|
CTRL-F12 Speed up emulation (Increase DOSox Cycles).
|
||||||
|
|
||||||
|
These are the default keybindings. They can be changed in the keymapper.
|
||||||
|
|
||||||
NOTE: Once you increase your DOSBox cycles beyond your computer's maximum
|
NOTE: Once you increase your DOSBox cycles beyond your computer's maximum
|
||||||
capacity, it will produce the same effect as slowing down the emulation.
|
capacity, it will produce the same effect as slowing down the emulation.
|
||||||
This maximum will vary from computer to computer, there is no standard.
|
This maximum will vary from computer to computer, there is no standard.
|
||||||
|
|
||||||
====================
|
|
||||||
System requirements:
|
|
||||||
====================
|
=============
|
||||||
|
6. Keymapper:
|
||||||
|
=============
|
||||||
|
|
||||||
|
When you start the keymapper (either with CTRL-F1 or -startmapper as a
|
||||||
|
commandline argument) you are presented with a virtual keyboard.
|
||||||
|
|
||||||
|
This virtual keyboard corresponds with the keys DOSBox will report to its
|
||||||
|
applications. If you click on a key with your mouse, you can see in the
|
||||||
|
lowerleft corner which key on your keyboard corresponds with it.
|
||||||
|
|
||||||
|
Event: EVENT
|
||||||
|
BIND: BIND
|
||||||
|
Add Del
|
||||||
|
mod1 hold Next
|
||||||
|
mod2
|
||||||
|
mod3
|
||||||
|
|
||||||
|
|
||||||
|
EVENT
|
||||||
|
The key DOSBox will report to the applications being emulated.
|
||||||
|
BIND
|
||||||
|
The key on your keyboard (as reported by SDL) which is connected to the
|
||||||
|
EVENT.
|
||||||
|
mod1,2,3
|
||||||
|
Modfiers. These are keys you need to have pressed as well, while pressing
|
||||||
|
BIND. mod1 = CTRL and mod2 = ALT. These are generally only used when you
|
||||||
|
want to change the special keys of DOSBox.
|
||||||
|
Add
|
||||||
|
Add a new BIND to this EVENT. Basicly add a key from your keyboard which
|
||||||
|
will produce the key EVENT in DOSBox.
|
||||||
|
Del
|
||||||
|
Delete the BIND to this EVENT. If an EVENT has no BINDS than it's not
|
||||||
|
possible to type this key in DOSBox.
|
||||||
|
Next
|
||||||
|
Cycle through the list of keys(BINDS) which map to this EVENT.
|
||||||
|
|
||||||
|
|
||||||
|
Example:
|
||||||
|
Q1. You want to have the X on your keyboard to type a Z in DOSBox.
|
||||||
|
A. With your mouse click on the Z on the keyboard mapper. Click "Add".
|
||||||
|
Now press the X key on your keyboard.
|
||||||
|
|
||||||
|
Q2. If you click "Next" a few times you will notice that the Z on your
|
||||||
|
keyboard also produces an Z in DOSBox.
|
||||||
|
A. Therefore select the Z again and click "Next" till you have the Z on
|
||||||
|
your keyboard. Now click "Del".
|
||||||
|
|
||||||
|
Q3. If you try it out in DOSBox you will notice that pressing X makes ZX
|
||||||
|
appear.
|
||||||
|
A. The X on your keyboard is still mapped to the X as well! Click on
|
||||||
|
the X in the keyboard mapper and search with "Next" till you find the
|
||||||
|
mapped key X. Click "Del".
|
||||||
|
|
||||||
|
|
||||||
|
If you change the default mapping you can save your changes by pressing
|
||||||
|
"Save". DOSBox will save the mapping to location specified in the configfile
|
||||||
|
(mapperfile=mapper.txt). At startup DOSBox will load your mapperfile if it's
|
||||||
|
present in the configfile.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
=======================
|
||||||
|
7. System requirements:
|
||||||
|
=======================
|
||||||
|
|
||||||
Fast machine. My guess would be pentium-2 400+ to get decent emulation
|
Fast machine. My guess would be pentium-2 400+ to get decent emulation
|
||||||
of games written for an 286 machine.
|
of games written for an 286 machine.
|
||||||
@ -206,9 +628,10 @@ them to run fast though!! Be sure to read the next section on how to speed
|
|||||||
it up somewhat.
|
it up somewhat.
|
||||||
|
|
||||||
|
|
||||||
================================
|
|
||||||
To run resource-demanding games:
|
===================================
|
||||||
================================
|
8. To run resource-demanding games:
|
||||||
|
===================================
|
||||||
|
|
||||||
DOSBox emulates the CPU, the sound and graphic cards, and some other
|
DOSBox emulates the CPU, the sound and graphic cards, and some other
|
||||||
stuff, all at the same time. You can overclock DOSBox by using CTRL+F12, but
|
stuff, all at the same time. You can overclock DOSBox by using CTRL+F12, but
|
||||||
@ -236,109 +659,31 @@ You can also try to disable the sound through the setup utility of the game
|
|||||||
to further reduce load on your CPU.
|
to further reduce load on your CPU.
|
||||||
|
|
||||||
|
|
||||||
====
|
|
||||||
FAQ:
|
|
||||||
====
|
|
||||||
|
|
||||||
Q: I've got a Z instead of a C at the prompt.
|
===================
|
||||||
A: In DOSBox you can mount directories as drives.
|
9. The Config File:
|
||||||
In win32: mount c D:\ would give you a C in DOSBox which points
|
===================
|
||||||
at D:\ in win32.
|
|
||||||
In linux: mount c /home/username would give you a C in DOSBox
|
|
||||||
which points at /home/username in Linux.
|
|
||||||
|
|
||||||
Q: The mouse doesn't work.
|
|
||||||
A: Normally dosbox detects the mouse being used by a game. If you click on
|
|
||||||
the screen then it should get locked and work.
|
|
||||||
Sometimes the dosbox mouse detection doesn't work with certain games. You
|
|
||||||
might have to force to lock the mouse then with ctrl-F10.
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
================
|
|
||||||
The Config File:
|
|
||||||
================
|
|
||||||
|
|
||||||
A config file can be generated by CONFIG.COM, which can be found on the
|
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
|
internal dosbox Z: drive when you start up dosbox. Look in the internal
|
||||||
programs section of the readme for usage of CONFIG.COM.
|
programs section of the readme for usage of CONFIG.COM.
|
||||||
You can edit the generated configfile to customize DOSBox.
|
You can edit the generated configfile to customize DOSBox.
|
||||||
|
|
||||||
The file is divided into several sections (the names have [] around it).
|
The file is divided into several sections (the names have [] around it).
|
||||||
Some sections have options which you can set.
|
Some sections have options which you can set.
|
||||||
# and % indicate comment-lines.
|
# and % indicate comment-lines.
|
||||||
The generated configfile contains the current settings. You can alter them and
|
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
|
If no configfile is specified with the -conf switch, DOSBox will look in the
|
||||||
current directory for dosbox.conf. Then it will look for ~/.dosboxrc (linux),
|
current directory for dosbox.conf. Then it will look for ~/.dosboxrc (Linux),
|
||||||
~\dosbox.conf (win32) or "~/Library/Preferences/DOSBox Preferences" (MACOSX).
|
~\dosbox.conf (Win32) or "~/Library/Preferences/DOSBox Preferences" (MACOSX).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
==================
|
======================
|
||||||
The Language File:
|
10. The Language File:
|
||||||
==================
|
======================
|
||||||
|
|
||||||
A language file can be generated by CONFIG.COM.
|
A language file can be generated by CONFIG.COM.
|
||||||
Read it and you will hopefully understand how to change it.
|
Read it and you will hopefully understand how to change it.
|
||||||
@ -347,16 +692,19 @@ 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.
|
There's a language= entry that can be changed with the filename.
|
||||||
|
|
||||||
|
|
||||||
====================================
|
|
||||||
Building your own version of DOSBox:
|
========================================
|
||||||
====================================
|
11. Building your own version of DOSBox:
|
||||||
|
========================================
|
||||||
|
|
||||||
Download the source.
|
Download the source.
|
||||||
Check the INSTALL in the source distribution.
|
Check the INSTALL in the source distribution.
|
||||||
|
|
||||||
===============
|
|
||||||
Special Thanks:
|
|
||||||
===============
|
===================
|
||||||
|
12. Special Thanks:
|
||||||
|
===================
|
||||||
|
|
||||||
Vlad R. of the vdmsound project for excellent sound blaster info.
|
Vlad R. of the vdmsound project for excellent sound blaster info.
|
||||||
Tatsuyuki Satoh of the Mame Team for making an excellent FM emulator.
|
Tatsuyuki Satoh of the Mame Team for making an excellent FM emulator.
|
||||||
@ -366,9 +714,12 @@ Pierre-Yves G
|
|||||||
Colin Snover for hosting our forum.
|
Colin Snover for hosting our forum.
|
||||||
The Beta Testers.
|
The Beta Testers.
|
||||||
|
|
||||||
========
|
|
||||||
Contact:
|
|
||||||
========
|
|
||||||
|
|
||||||
Harekiet harekiet@zophar.net
|
|
||||||
|
============
|
||||||
|
13. Contact:
|
||||||
|
============
|
||||||
|
|
||||||
|
See the site:
|
||||||
http://dosbox.sourceforge.net
|
http://dosbox.sourceforge.net
|
||||||
|
for an emailaddress (The Crew-page).
|
||||||
|
51
acinclude.m4
51
acinclude.m4
@ -1,7 +1,7 @@
|
|||||||
dnl AM_PATH_SDL([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
|
dnl AM_PATH_SDL([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
|
||||||
dnl Test for SDL, and define SDL_CFLAGS and SDL_LIBS
|
dnl Test for SDL, and define SDL_CFLAGS and SDL_LIBS
|
||||||
dnl
|
dnl
|
||||||
AC_DEFUN(AM_PATH_SDL,
|
AC_DEFUN([AM_PATH_SDL],
|
||||||
[dnl
|
[dnl
|
||||||
dnl Get the cflags and libraries from the sdl-config script
|
dnl Get the cflags and libraries from the sdl-config script
|
||||||
dnl
|
dnl
|
||||||
@ -174,7 +174,7 @@ dnl
|
|||||||
dnl For backwards compatibility, if ACTION_IF_NOT_FOUND is not specified,
|
dnl For backwards compatibility, if ACTION_IF_NOT_FOUND is not specified,
|
||||||
dnl and the alsa libraries are not found, a fatal AC_MSG_ERROR() will result.
|
dnl and the alsa libraries are not found, a fatal AC_MSG_ERROR() will result.
|
||||||
dnl
|
dnl
|
||||||
AC_DEFUN(AM_PATH_ALSA,
|
AC_DEFUN([AM_PATH_ALSA],
|
||||||
[dnl Save the original CFLAGS, LDFLAGS, and LIBS
|
[dnl Save the original CFLAGS, LDFLAGS, and LIBS
|
||||||
alsa_save_CFLAGS="$CFLAGS"
|
alsa_save_CFLAGS="$CFLAGS"
|
||||||
alsa_save_LDFLAGS="$LDFLAGS"
|
alsa_save_LDFLAGS="$LDFLAGS"
|
||||||
@ -305,7 +305,7 @@ AC_SUBST(ALSA_LIBS)
|
|||||||
|
|
||||||
AH_TOP([
|
AH_TOP([
|
||||||
/*
|
/*
|
||||||
* 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
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -331,4 +331,49 @@ AH_BOTTOM([#if C_HAS_ATTRIBUTE
|
|||||||
#define GCC_ATTRIBUTE(x) /* attribute not supported */
|
#define GCC_ATTRIBUTE(x) /* attribute not supported */
|
||||||
#endif])
|
#endif])
|
||||||
|
|
||||||
|
AH_BOTTOM([
|
||||||
|
typedef double Real64;
|
||||||
|
|
||||||
|
#if SIZEOF_UNSIGNED_CHAR != 1
|
||||||
|
# error "sizeof (unsigned char) != 1"
|
||||||
|
#else
|
||||||
|
typedef unsigned char Bit8u;
|
||||||
|
typedef signed char Bit8s;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SIZEOF_UNSIGNED_SHORT != 2
|
||||||
|
# error "sizeof (unsigned short) != 2"
|
||||||
|
#else
|
||||||
|
typedef unsigned short Bit16u;
|
||||||
|
typedef signed short Bit16s;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SIZEOF_UNSIGNED_INT == 4
|
||||||
|
typedef unsigned int Bit32u;
|
||||||
|
typedef signed int Bit32s;
|
||||||
|
#elif SIZEOF_UNSIGNED_LONG == 4
|
||||||
|
typedef unsigned long Bit32u;
|
||||||
|
typedef signed long Bit32s;
|
||||||
|
#else
|
||||||
|
# error "can't find sizeof(type) of 4 bytes!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SIZEOF_UNSIGNED_LONG == 8
|
||||||
|
typedef unsigned long Bit64u;
|
||||||
|
typedef signed long Bit64s;
|
||||||
|
#elif SIZEOF_UNSIGNED_LONG_LONG == 8
|
||||||
|
typedef unsigned long long Bit64u;
|
||||||
|
typedef signed long long Bit64s;
|
||||||
|
#else
|
||||||
|
# error "can't find data type of 8 bytes"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SIZEOF_INT_P == 4
|
||||||
|
typedef Bit32u Bitu;
|
||||||
|
typedef Bit32s Bits;
|
||||||
|
#else
|
||||||
|
typedef Bit64u Bitu;
|
||||||
|
typedef Bit64s Bits;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
])
|
||||||
|
51
aclocal.m4
vendored
51
aclocal.m4
vendored
@ -14,7 +14,7 @@
|
|||||||
dnl AM_PATH_SDL([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
|
dnl AM_PATH_SDL([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
|
||||||
dnl Test for SDL, and define SDL_CFLAGS and SDL_LIBS
|
dnl Test for SDL, and define SDL_CFLAGS and SDL_LIBS
|
||||||
dnl
|
dnl
|
||||||
AC_DEFUN(AM_PATH_SDL,
|
AC_DEFUN([AM_PATH_SDL],
|
||||||
[dnl
|
[dnl
|
||||||
dnl Get the cflags and libraries from the sdl-config script
|
dnl Get the cflags and libraries from the sdl-config script
|
||||||
dnl
|
dnl
|
||||||
@ -187,7 +187,7 @@ dnl
|
|||||||
dnl For backwards compatibility, if ACTION_IF_NOT_FOUND is not specified,
|
dnl For backwards compatibility, if ACTION_IF_NOT_FOUND is not specified,
|
||||||
dnl and the alsa libraries are not found, a fatal AC_MSG_ERROR() will result.
|
dnl and the alsa libraries are not found, a fatal AC_MSG_ERROR() will result.
|
||||||
dnl
|
dnl
|
||||||
AC_DEFUN(AM_PATH_ALSA,
|
AC_DEFUN([AM_PATH_ALSA],
|
||||||
[dnl Save the original CFLAGS, LDFLAGS, and LIBS
|
[dnl Save the original CFLAGS, LDFLAGS, and LIBS
|
||||||
alsa_save_CFLAGS="$CFLAGS"
|
alsa_save_CFLAGS="$CFLAGS"
|
||||||
alsa_save_LDFLAGS="$LDFLAGS"
|
alsa_save_LDFLAGS="$LDFLAGS"
|
||||||
@ -318,7 +318,7 @@ AC_SUBST(ALSA_LIBS)
|
|||||||
|
|
||||||
AH_TOP([
|
AH_TOP([
|
||||||
/*
|
/*
|
||||||
* 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
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -344,7 +344,52 @@ AH_BOTTOM([#if C_HAS_ATTRIBUTE
|
|||||||
#define GCC_ATTRIBUTE(x) /* attribute not supported */
|
#define GCC_ATTRIBUTE(x) /* attribute not supported */
|
||||||
#endif])
|
#endif])
|
||||||
|
|
||||||
|
AH_BOTTOM([
|
||||||
|
typedef double Real64;
|
||||||
|
|
||||||
|
#if SIZEOF_UNSIGNED_CHAR != 1
|
||||||
|
# error "sizeof (unsigned char) != 1"
|
||||||
|
#else
|
||||||
|
typedef unsigned char Bit8u;
|
||||||
|
typedef signed char Bit8s;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SIZEOF_UNSIGNED_SHORT != 2
|
||||||
|
# error "sizeof (unsigned short) != 2"
|
||||||
|
#else
|
||||||
|
typedef unsigned short Bit16u;
|
||||||
|
typedef signed short Bit16s;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SIZEOF_UNSIGNED_INT == 4
|
||||||
|
typedef unsigned int Bit32u;
|
||||||
|
typedef signed int Bit32s;
|
||||||
|
#elif SIZEOF_UNSIGNED_LONG == 4
|
||||||
|
typedef unsigned long Bit32u;
|
||||||
|
typedef signed long Bit32s;
|
||||||
|
#else
|
||||||
|
# error "can't find sizeof(type) of 4 bytes!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SIZEOF_UNSIGNED_LONG == 8
|
||||||
|
typedef unsigned long Bit64u;
|
||||||
|
typedef signed long Bit64s;
|
||||||
|
#elif SIZEOF_UNSIGNED_LONG_LONG == 8
|
||||||
|
typedef unsigned long long Bit64u;
|
||||||
|
typedef signed long long Bit64s;
|
||||||
|
#else
|
||||||
|
# error "can't find data type of 8 bytes"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SIZEOF_INT_P == 4
|
||||||
|
typedef Bit32u Bitu;
|
||||||
|
typedef Bit32s Bits;
|
||||||
|
#else
|
||||||
|
typedef Bit64u Bitu;
|
||||||
|
typedef Bit64s Bits;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
])
|
||||||
|
|
||||||
# Do all the work for Automake. -*- Autoconf -*-
|
# Do all the work for Automake. -*- Autoconf -*-
|
||||||
|
|
||||||
|
751
config.guess
vendored
751
config.guess
vendored
File diff suppressed because it is too large
Load Diff
82
config.h.in
82
config.h.in
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 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
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -26,6 +26,9 @@
|
|||||||
/* Define to 1 to enable internal debugger, requires libcurses */
|
/* Define to 1 to enable internal debugger, requires libcurses */
|
||||||
#undef C_DEBUG
|
#undef C_DEBUG
|
||||||
|
|
||||||
|
/* Define to 1 if you want serial passthrough support (Win32 only). */
|
||||||
|
#undef C_DIRECTSERIAL
|
||||||
|
|
||||||
/* Define to 1 to use x86 dynamic cpu core */
|
/* Define to 1 to use x86 dynamic cpu core */
|
||||||
#undef C_DYNAMIC_X86
|
#undef C_DYNAMIC_X86
|
||||||
|
|
||||||
@ -41,12 +44,21 @@
|
|||||||
/* The type of cpu this host has */
|
/* The type of cpu this host has */
|
||||||
#undef C_HOSTCPU
|
#undef C_HOSTCPU
|
||||||
|
|
||||||
|
/* Define to 1 to enable IPX over Internet networking, requires SDL_net */
|
||||||
|
#undef C_IPX
|
||||||
|
|
||||||
/* Define to 1 to enable internal modem support, requires SDL_net */
|
/* Define to 1 to enable internal modem support, requires SDL_net */
|
||||||
#undef C_MODEM
|
#undef C_MODEM
|
||||||
|
|
||||||
/* Define to 1 to use opengl display output support */
|
/* Define to 1 to use opengl display output support */
|
||||||
#undef C_OPENGL
|
#undef C_OPENGL
|
||||||
|
|
||||||
|
/* Define to 1 to enable SDL_sound support */
|
||||||
|
#undef C_SDL_SOUND
|
||||||
|
|
||||||
|
/* Define to 1 if you have setpriority support */
|
||||||
|
#undef C_SET_PRIORITY
|
||||||
|
|
||||||
/* Define to 1 to enable screenshots, requires libpng */
|
/* Define to 1 to enable screenshots, requires libpng */
|
||||||
#undef C_SSHOT
|
#undef C_SSHOT
|
||||||
|
|
||||||
@ -59,6 +71,9 @@
|
|||||||
/* Define to 1 to use ALSA for MIDI */
|
/* Define to 1 to use ALSA for MIDI */
|
||||||
#undef HAVE_ALSA
|
#undef HAVE_ALSA
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <ddraw.h> header file. */
|
||||||
|
#undef HAVE_DDRAW_H
|
||||||
|
|
||||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||||
#undef HAVE_INTTYPES_H
|
#undef HAVE_INTTYPES_H
|
||||||
|
|
||||||
@ -113,6 +128,24 @@
|
|||||||
/* Define to the version of this package. */
|
/* Define to the version of this package. */
|
||||||
#undef PACKAGE_VERSION
|
#undef PACKAGE_VERSION
|
||||||
|
|
||||||
|
/* The size of a `int *', as computed by sizeof. */
|
||||||
|
#undef SIZEOF_INT_P
|
||||||
|
|
||||||
|
/* The size of a `unsigned char', as computed by sizeof. */
|
||||||
|
#undef SIZEOF_UNSIGNED_CHAR
|
||||||
|
|
||||||
|
/* The size of a `unsigned int', as computed by sizeof. */
|
||||||
|
#undef SIZEOF_UNSIGNED_INT
|
||||||
|
|
||||||
|
/* The size of a `unsigned long', as computed by sizeof. */
|
||||||
|
#undef SIZEOF_UNSIGNED_LONG
|
||||||
|
|
||||||
|
/* The size of a `unsigned long long', as computed by sizeof. */
|
||||||
|
#undef SIZEOF_UNSIGNED_LONG_LONG
|
||||||
|
|
||||||
|
/* The size of a `unsigned short', as computed by sizeof. */
|
||||||
|
#undef SIZEOF_UNSIGNED_SHORT
|
||||||
|
|
||||||
/* Define to 1 if you have the ANSI C header files. */
|
/* Define to 1 if you have the ANSI C header files. */
|
||||||
#undef STDC_HEADERS
|
#undef STDC_HEADERS
|
||||||
|
|
||||||
@ -145,3 +178,50 @@
|
|||||||
#else
|
#else
|
||||||
#define GCC_ATTRIBUTE(x) /* attribute not supported */
|
#define GCC_ATTRIBUTE(x) /* attribute not supported */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
typedef double Real64;
|
||||||
|
|
||||||
|
#if SIZEOF_UNSIGNED_CHAR != 1
|
||||||
|
# error "sizeof (unsigned char) != 1"
|
||||||
|
#else
|
||||||
|
typedef unsigned char Bit8u;
|
||||||
|
typedef signed char Bit8s;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SIZEOF_UNSIGNED_SHORT != 2
|
||||||
|
# error "sizeof (unsigned short) != 2"
|
||||||
|
#else
|
||||||
|
typedef unsigned short Bit16u;
|
||||||
|
typedef signed short Bit16s;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SIZEOF_UNSIGNED_INT == 4
|
||||||
|
typedef unsigned int Bit32u;
|
||||||
|
typedef signed int Bit32s;
|
||||||
|
#elif SIZEOF_UNSIGNED_LONG == 4
|
||||||
|
typedef unsigned long Bit32u;
|
||||||
|
typedef signed long Bit32s;
|
||||||
|
#else
|
||||||
|
# error "can't find sizeof(type) of 4 bytes!"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SIZEOF_UNSIGNED_LONG == 8
|
||||||
|
typedef unsigned long Bit64u;
|
||||||
|
typedef signed long Bit64s;
|
||||||
|
#elif SIZEOF_UNSIGNED_LONG_LONG == 8
|
||||||
|
typedef unsigned long long Bit64u;
|
||||||
|
typedef signed long long Bit64s;
|
||||||
|
#else
|
||||||
|
# error "can't find data type of 8 bytes"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if SIZEOF_INT_P == 4
|
||||||
|
typedef Bit32u Bitu;
|
||||||
|
typedef Bit32s Bits;
|
||||||
|
#else
|
||||||
|
typedef Bit64u Bitu;
|
||||||
|
typedef Bit64s Bits;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
57
config.sub
vendored
57
config.sub
vendored
@ -1,9 +1,9 @@
|
|||||||
#! /bin/sh
|
#! /bin/sh
|
||||||
# Configuration validation subroutine script.
|
# Configuration validation subroutine script.
|
||||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||||
# 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
# 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
|
||||||
|
|
||||||
timestamp='2004-01-05'
|
timestamp='2004-06-24'
|
||||||
|
|
||||||
# This file is (in principle) common to ALL GNU software.
|
# This file is (in principle) common to ALL GNU software.
|
||||||
# The presence of a machine in this file suggests that SOME GNU software
|
# The presence of a machine in this file suggests that SOME GNU software
|
||||||
@ -70,7 +70,7 @@ Report bugs and patches to <config-patches@gnu.org>."
|
|||||||
version="\
|
version="\
|
||||||
GNU config.sub ($timestamp)
|
GNU config.sub ($timestamp)
|
||||||
|
|
||||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
|
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
|
||||||
Free Software Foundation, Inc.
|
Free Software Foundation, Inc.
|
||||||
|
|
||||||
This is free software; see the source for copying conditions. There is NO
|
This is free software; see the source for copying conditions. There is NO
|
||||||
@ -145,7 +145,7 @@ case $os in
|
|||||||
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
|
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
|
||||||
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
|
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
|
||||||
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
|
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
|
||||||
-apple | -axis)
|
-apple | -axis | -knuth | -cray)
|
||||||
os=
|
os=
|
||||||
basic_machine=$1
|
basic_machine=$1
|
||||||
;;
|
;;
|
||||||
@ -237,7 +237,7 @@ case $basic_machine in
|
|||||||
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
|
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
|
||||||
| i370 | i860 | i960 | ia64 \
|
| i370 | i860 | i960 | ia64 \
|
||||||
| ip2k | iq2000 \
|
| ip2k | iq2000 \
|
||||||
| m32r | m68000 | m68k | m88k | mcore \
|
| m32r | m32rle | m68000 | m68k | m88k | mcore \
|
||||||
| mips | mipsbe | mipseb | mipsel | mipsle \
|
| mips | mipsbe | mipseb | mipsel | mipsle \
|
||||||
| mips16 \
|
| mips16 \
|
||||||
| mips64 | mips64el \
|
| mips64 | mips64el \
|
||||||
@ -262,7 +262,7 @@ case $basic_machine in
|
|||||||
| pyramid \
|
| pyramid \
|
||||||
| sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
|
| sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
|
||||||
| sh64 | sh64le \
|
| sh64 | sh64le \
|
||||||
| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
|
| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv8 | sparcv9 | sparcv9b \
|
||||||
| strongarm \
|
| strongarm \
|
||||||
| tahoe | thumb | tic4x | tic80 | tron \
|
| tahoe | thumb | tic4x | tic80 | tron \
|
||||||
| v850 | v850e \
|
| v850 | v850e \
|
||||||
@ -300,7 +300,7 @@ case $basic_machine in
|
|||||||
| avr-* \
|
| avr-* \
|
||||||
| bs2000-* \
|
| bs2000-* \
|
||||||
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
|
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
|
||||||
| clipper-* | cydra-* \
|
| clipper-* | craynv-* | cydra-* \
|
||||||
| d10v-* | d30v-* | dlx-* \
|
| d10v-* | d30v-* | dlx-* \
|
||||||
| elxsi-* \
|
| elxsi-* \
|
||||||
| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
|
| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
|
||||||
@ -308,7 +308,7 @@ case $basic_machine in
|
|||||||
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
|
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
|
||||||
| i*86-* | i860-* | i960-* | ia64-* \
|
| i*86-* | i860-* | i960-* | ia64-* \
|
||||||
| ip2k-* | iq2000-* \
|
| ip2k-* | iq2000-* \
|
||||||
| m32r-* \
|
| m32r-* | m32rle-* \
|
||||||
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
|
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
|
||||||
| m88110-* | m88k-* | mcore-* \
|
| m88110-* | m88k-* | mcore-* \
|
||||||
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
|
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
|
||||||
@ -326,8 +326,9 @@ case $basic_machine in
|
|||||||
| mipsisa64sb1-* | mipsisa64sb1el-* \
|
| mipsisa64sb1-* | mipsisa64sb1el-* \
|
||||||
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
|
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
|
||||||
| mipstx39-* | mipstx39el-* \
|
| mipstx39-* | mipstx39el-* \
|
||||||
|
| mmix-* \
|
||||||
| msp430-* \
|
| msp430-* \
|
||||||
| none-* | np1-* | nv1-* | ns16k-* | ns32k-* \
|
| none-* | np1-* | ns16k-* | ns32k-* \
|
||||||
| orion-* \
|
| orion-* \
|
||||||
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
|
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
|
||||||
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
|
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
|
||||||
@ -336,7 +337,7 @@ case $basic_machine in
|
|||||||
| sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
|
| sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
|
||||||
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
|
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
|
||||||
| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
|
| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
|
||||||
| sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
|
| sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
|
||||||
| tahoe-* | thumb-* \
|
| tahoe-* | thumb-* \
|
||||||
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
|
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
|
||||||
| tron-* \
|
| tron-* \
|
||||||
@ -363,6 +364,9 @@ case $basic_machine in
|
|||||||
basic_machine=a29k-amd
|
basic_machine=a29k-amd
|
||||||
os=-udi
|
os=-udi
|
||||||
;;
|
;;
|
||||||
|
abacus)
|
||||||
|
basic_machine=abacus-unknown
|
||||||
|
;;
|
||||||
adobe68k)
|
adobe68k)
|
||||||
basic_machine=m68010-adobe
|
basic_machine=m68010-adobe
|
||||||
os=-scout
|
os=-scout
|
||||||
@ -442,12 +446,24 @@ case $basic_machine in
|
|||||||
basic_machine=j90-cray
|
basic_machine=j90-cray
|
||||||
os=-unicos
|
os=-unicos
|
||||||
;;
|
;;
|
||||||
|
craynv)
|
||||||
|
basic_machine=craynv-cray
|
||||||
|
os=-unicosmp
|
||||||
|
;;
|
||||||
|
cr16c)
|
||||||
|
basic_machine=cr16c-unknown
|
||||||
|
os=-elf
|
||||||
|
;;
|
||||||
crds | unos)
|
crds | unos)
|
||||||
basic_machine=m68k-crds
|
basic_machine=m68k-crds
|
||||||
;;
|
;;
|
||||||
cris | cris-* | etrax*)
|
cris | cris-* | etrax*)
|
||||||
basic_machine=cris-axis
|
basic_machine=cris-axis
|
||||||
;;
|
;;
|
||||||
|
crx)
|
||||||
|
basic_machine=crx-unknown
|
||||||
|
os=-elf
|
||||||
|
;;
|
||||||
da30 | da30-*)
|
da30 | da30-*)
|
||||||
basic_machine=m68k-da30
|
basic_machine=m68k-da30
|
||||||
;;
|
;;
|
||||||
@ -648,10 +664,6 @@ case $basic_machine in
|
|||||||
mips3*)
|
mips3*)
|
||||||
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
|
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
|
||||||
;;
|
;;
|
||||||
mmix*)
|
|
||||||
basic_machine=mmix-knuth
|
|
||||||
os=-mmixware
|
|
||||||
;;
|
|
||||||
monitor)
|
monitor)
|
||||||
basic_machine=m68k-rom68k
|
basic_machine=m68k-rom68k
|
||||||
os=-coff
|
os=-coff
|
||||||
@ -732,10 +744,6 @@ case $basic_machine in
|
|||||||
np1)
|
np1)
|
||||||
basic_machine=np1-gould
|
basic_machine=np1-gould
|
||||||
;;
|
;;
|
||||||
nv1)
|
|
||||||
basic_machine=nv1-cray
|
|
||||||
os=-unicosmp
|
|
||||||
;;
|
|
||||||
nsr-tandem)
|
nsr-tandem)
|
||||||
basic_machine=nsr-tandem
|
basic_machine=nsr-tandem
|
||||||
;;
|
;;
|
||||||
@ -1048,6 +1056,9 @@ case $basic_machine in
|
|||||||
romp)
|
romp)
|
||||||
basic_machine=romp-ibm
|
basic_machine=romp-ibm
|
||||||
;;
|
;;
|
||||||
|
mmix)
|
||||||
|
basic_machine=mmix-knuth
|
||||||
|
;;
|
||||||
rs6000)
|
rs6000)
|
||||||
basic_machine=rs6000-ibm
|
basic_machine=rs6000-ibm
|
||||||
;;
|
;;
|
||||||
@ -1070,7 +1081,7 @@ case $basic_machine in
|
|||||||
sh64)
|
sh64)
|
||||||
basic_machine=sh64-unknown
|
basic_machine=sh64-unknown
|
||||||
;;
|
;;
|
||||||
sparc | sparcv9 | sparcv9b)
|
sparc | sparcv8 | sparcv9 | sparcv9b)
|
||||||
basic_machine=sparc-sun
|
basic_machine=sparc-sun
|
||||||
;;
|
;;
|
||||||
cydra)
|
cydra)
|
||||||
@ -1143,8 +1154,9 @@ case $os in
|
|||||||
| -aos* \
|
| -aos* \
|
||||||
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
|
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
|
||||||
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
|
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
|
||||||
| -hiux* | -386bsd* | -knetbsd* | -netbsd* | -openbsd* | -kfreebsd* | -freebsd* | -riscix* \
|
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \
|
||||||
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
|
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
|
||||||
|
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
|
||||||
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
|
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
|
||||||
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
|
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
|
||||||
| -chorusos* | -chorusrdb* \
|
| -chorusos* | -chorusrdb* \
|
||||||
@ -1362,6 +1374,9 @@ case $basic_machine in
|
|||||||
*-ibm)
|
*-ibm)
|
||||||
os=-aix
|
os=-aix
|
||||||
;;
|
;;
|
||||||
|
*-knuth)
|
||||||
|
os=-mmixware
|
||||||
|
;;
|
||||||
*-wec)
|
*-wec)
|
||||||
os=-proelf
|
os=-proelf
|
||||||
;;
|
;;
|
||||||
|
39
configure.in
39
configure.in
@ -1,5 +1,5 @@
|
|||||||
dnl Init.
|
dnl Init.
|
||||||
AC_INIT(dosbox,0.61)
|
AC_INIT(dosbox,0.62)
|
||||||
AC_PREREQ(2.50)
|
AC_PREREQ(2.50)
|
||||||
AC_CONFIG_SRCDIR(README)
|
AC_CONFIG_SRCDIR(README)
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ AM_PATH_SDL($SDL_VERSION,
|
|||||||
AC_MSG_ERROR([*** SDL version $SDL_VERSION not found!])
|
AC_MSG_ERROR([*** SDL version $SDL_VERSION not found!])
|
||||||
)
|
)
|
||||||
LIBS="$LIBS $SDL_LIBS"
|
LIBS="$LIBS $SDL_LIBS"
|
||||||
CXXFLAGS="$CXXFLAGS $SDL_CFLAGS"
|
CPPFLAGS="$CPPFLAGS $SDL_CFLAGS"
|
||||||
|
|
||||||
dnl Checks for header files.
|
dnl Checks for header files.
|
||||||
|
|
||||||
@ -35,7 +35,12 @@ AC_C_CONST
|
|||||||
AC_C_INLINE
|
AC_C_INLINE
|
||||||
AC_TYPE_SIZE_T
|
AC_TYPE_SIZE_T
|
||||||
AC_STRUCT_TM
|
AC_STRUCT_TM
|
||||||
|
AC_CHECK_SIZEOF(unsigned char)
|
||||||
|
AC_CHECK_SIZEOF(unsigned short)
|
||||||
|
AC_CHECK_SIZEOF(unsigned int)
|
||||||
|
AC_CHECK_SIZEOF(unsigned long)
|
||||||
|
AC_CHECK_SIZEOF(unsigned long long)
|
||||||
|
AC_CHECK_SIZEOF(int *)
|
||||||
|
|
||||||
AC_MSG_CHECKING(if environ can be included)
|
AC_MSG_CHECKING(if environ can be included)
|
||||||
AC_TRY_LINK([#include <unistd.h>
|
AC_TRY_LINK([#include <unistd.h>
|
||||||
@ -143,13 +148,15 @@ else
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
AH_TEMPLATE(C_MODEM,[Define to 1 to enable internal modem support, requires SDL_net])
|
AH_TEMPLATE(C_MODEM,[Define to 1 to enable internal modem support, requires SDL_net])
|
||||||
AC_CHECK_HEADER(SDL/SDL_net.h,have_sdl_net_h=yes,)
|
AH_TEMPLATE(C_IPX,[Define to 1 to enable IPX over Internet networking, requires SDL_net])
|
||||||
|
AC_CHECK_HEADER(SDL_net.h,have_sdl_net_h=yes,)
|
||||||
AC_CHECK_LIB(SDL_net, SDLNet_Init, have_sdl_net_lib=yes, , )
|
AC_CHECK_LIB(SDL_net, SDLNet_Init, have_sdl_net_lib=yes, , )
|
||||||
if test x$have_sdl_net_lib = xyes -a x$have_sdl_net_h = xyes ; then
|
if test x$have_sdl_net_lib = xyes -a x$have_sdl_net_h = xyes ; then
|
||||||
LIBS="$LIBS -lSDL_net"
|
LIBS="$LIBS -lSDL_net"
|
||||||
AC_DEFINE(C_MODEM,1)
|
AC_DEFINE(C_MODEM,1)
|
||||||
|
AC_DEFINE(C_IPX,1)
|
||||||
else
|
else
|
||||||
AC_MSG_WARN([Can't find SDL_net, internal modem disabled])
|
AC_MSG_WARN([Can't find SDL_net, internal modem and ipx disabled])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AH_TEMPLATE(C_OPENGL,[Define to 1 to use opengl display output support])
|
AH_TEMPLATE(C_OPENGL,[Define to 1 to use opengl display output support])
|
||||||
@ -170,10 +177,32 @@ else
|
|||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
AH_TEMPLATE(C_SDL_SOUND,[Define to 1 to enable SDL_sound support])
|
||||||
|
AC_CHECK_HEADER(SDL/SDL_sound.h,have_SDL_sound_h=yes,)
|
||||||
|
AC_CHECK_LIB(SDL_sound, Sound_Init, have_SDL_sound_lib=yes,,)
|
||||||
|
if test x$have_SDL_sound_h = xyes -a x$have_SDL_sound_lib = xyes ; then
|
||||||
|
LIBS="$LIBS -lSDL_sound"
|
||||||
|
AC_DEFINE(C_SDL_SOUND,1)
|
||||||
|
else
|
||||||
|
AC_MSG_WARN([Can't find libSDL_sound, libSDL_sound support disabled])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AH_TEMPLATE(C_SET_PRIORITY,[Define to 1 if you have setpriority support])
|
||||||
|
AC_MSG_CHECKING(for setpriority support)
|
||||||
|
AC_LINK_IFELSE([
|
||||||
|
#include <sys/resource.h>
|
||||||
|
int main(int argc,char * argv[]) {
|
||||||
|
return setpriority (PRIO_PROCESS, 0,PRIO_MIN+PRIO_MAX);
|
||||||
|
};
|
||||||
|
],AC_MSG_RESULT(yes);AC_DEFINE(C_SET_PRIORITY,1),AC_MSG_RESULT(no))
|
||||||
|
|
||||||
|
|
||||||
dnl Some host detection and actions for them
|
dnl Some host detection and actions for them
|
||||||
case "$target" in
|
case "$target" in
|
||||||
*-*-cygwin* | *-*-mingw32*)
|
*-*-cygwin* | *-*-mingw32*)
|
||||||
LIBS="$LIBS -lwinmm"
|
LIBS="$LIBS -lwinmm"
|
||||||
|
AC_CHECK_HEADERS(ddraw.h)
|
||||||
|
AC_DEFINE(C_DIRECTSERIAL, 1, [ Define to 1 if you want serial passthrough support (Win32 only).])
|
||||||
;;
|
;;
|
||||||
*-*-darwin*)
|
*-*-darwin*)
|
||||||
dnl We have a problem here: both MacOS X and Darwin report
|
dnl We have a problem here: both MacOS X and Darwin report
|
||||||
|
@ -1,16 +1,20 @@
|
|||||||
.\" Hey, EMACS: -*- nroff -*-
|
.\" Hey, EMACS: -*- nroff -*-
|
||||||
.TH DOSBOX 1 "October 5, 2003"
|
.TH DOSBOX 1 "Sept 23, 2004"
|
||||||
.\" Please adjust this date whenever revising the manpage.
|
.\" Please adjust this date whenever revising the manpage.
|
||||||
.SH NAME
|
.SH NAME
|
||||||
dosbox \- an x86/DOS emulator with sound/graphics
|
dosbox \- an x86/DOS emulator with sound/graphics
|
||||||
.SH SYNOPSIS
|
.SH SYNOPSIS
|
||||||
.B dosbox
|
.B dosbox
|
||||||
.B [\-fullscreen]
|
.B [\-fullscreen]
|
||||||
|
.B [\-startmapper]
|
||||||
.BI "[\-conf " configfile ]
|
.BI "[\-conf " configfile ]
|
||||||
.BI "[\-lang " langfile ]
|
.BI "[\-lang " langfile ]
|
||||||
.B [file]
|
.B [file]
|
||||||
.BI "[\-c " command ]
|
.BI "[\-c " command ]
|
||||||
.B [\-exit]
|
.B [\-exit]
|
||||||
|
.BI "[\-machine " machinetype ]
|
||||||
|
.LP
|
||||||
|
.B dosbox -version
|
||||||
.SH DESCRIPTION
|
.SH DESCRIPTION
|
||||||
This manual page briefly documents
|
This manual page briefly documents
|
||||||
.BR "dosbox" ", an x86/DOS emulator."
|
.BR "dosbox" ", an x86/DOS emulator."
|
||||||
@ -22,6 +26,9 @@ A summary of options is included below.
|
|||||||
.B \-fullscreen
|
.B \-fullscreen
|
||||||
.RB "Start " dosbox " in fullscreen mode."
|
.RB "Start " dosbox " in fullscreen mode."
|
||||||
.TP
|
.TP
|
||||||
|
.B \-startmapper
|
||||||
|
.RB "Start the internal keymapper on startup of " dosbox ". You can use it to change the keys " dosbox " uses."
|
||||||
|
.TP
|
||||||
.BI \-c " command"
|
.BI \-c " command"
|
||||||
.RI "Runs the specified " command " before running "
|
.RI "Runs the specified " command " before running "
|
||||||
.BR file .
|
.BR file .
|
||||||
@ -38,6 +45,13 @@ A summary of options is included below.
|
|||||||
.TP
|
.TP
|
||||||
.B \-exit
|
.B \-exit
|
||||||
.BR dosbox " will exit after running the program specified by " file .
|
.BR dosbox " will exit after running the program specified by " file .
|
||||||
|
.TP
|
||||||
|
.BI \-machine " machinetype
|
||||||
|
.RB "Setup " dosbox " to emulate a specific type of machine."
|
||||||
|
.RI "Valid choices are: " "hercules, cga, tandy, vga(default)".
|
||||||
|
.TP
|
||||||
|
.B \-version
|
||||||
|
Output version information and exit. Useful for frontends.
|
||||||
.SH "INTERNAL COMMANDS"
|
.SH "INTERNAL COMMANDS"
|
||||||
.B dosbox
|
.B dosbox
|
||||||
supports most of the DOS commands found in command.com. In addition, the
|
supports most of the DOS commands found in command.com. In addition, the
|
||||||
@ -46,7 +60,7 @@ following extra commands are available:
|
|||||||
.BI "MOUNT [\-t " type "] [\-size " size ]
|
.BI "MOUNT [\-t " type "] [\-size " size ]
|
||||||
.I driveletter sourcedirectory
|
.I driveletter sourcedirectory
|
||||||
.B [\-aspi] [\-ioctl]
|
.B [\-aspi] [\-ioctl]
|
||||||
.BI "[\-usecd " number "] [\-label " drivelabel ]
|
.BI "[\-usecd " number "] [\-label " drivelabel "] [\-freesize " freesize ]
|
||||||
.LP
|
.LP
|
||||||
.B MOUNT \-cd
|
.B MOUNT \-cd
|
||||||
.LP
|
.LP
|
||||||
@ -63,7 +77,11 @@ The local directory you want to have inside dosbox.
|
|||||||
Type of the mounted directory. Supported are: dir (standard), floppy, cdrom.
|
Type of the mounted directory. Supported are: dir (standard), floppy, cdrom.
|
||||||
.TP
|
.TP
|
||||||
.BI \-size " drivesize"
|
.BI \-size " drivesize"
|
||||||
Sets the size of the drive.
|
Sets the size of the drive. See the examples in the README for details.
|
||||||
|
.TP
|
||||||
|
.BI \-freesize " freesize"
|
||||||
|
Sets the amount of free space available on a drive in MB's. This is a more
|
||||||
|
.RB "simple version of " \-size .
|
||||||
.TP
|
.TP
|
||||||
.BI \-label " drivelabel"
|
.BI \-label " drivelabel"
|
||||||
.RI "Sets the name of the drive to " drivelabel ". Needed on some"
|
.RI "Sets the name of the drive to " drivelabel ". Needed on some"
|
||||||
@ -123,6 +141,30 @@ The amount of memory to eat up (in kb). Example -32, -64 or -128
|
|||||||
.B \-f
|
.B \-f
|
||||||
Frees all memory eaten up by loadfix.
|
Frees all memory eaten up by loadfix.
|
||||||
.RE
|
.RE
|
||||||
|
.TP
|
||||||
|
.B IMGMOUNT
|
||||||
|
.LP
|
||||||
|
.RB "A utility to mount disk images and CD-ROM images in " DOSBox .
|
||||||
|
.TP
|
||||||
|
.RB "Read the " README " of " DOSBox " for the full and correct syntax."
|
||||||
|
.RE
|
||||||
|
.TP
|
||||||
|
.B BOOT
|
||||||
|
.LP
|
||||||
|
.RB "Boot will start floppy images or hard disk images independent of the operating system emulation offered by " DOSBox ". This will allow you to play booter floppies or boot to other operating systems inside "DOSBox .
|
||||||
|
.TP
|
||||||
|
.RB "Read the " README " of " DOSBox " for the full and correct syntax."
|
||||||
|
.RE
|
||||||
|
.TP
|
||||||
|
.B IPX
|
||||||
|
.LP
|
||||||
|
.RB "You need to enable IPX networking in the configuration file of "DOSBox .
|
||||||
|
.RB "All of the IPX networking is managed through the internal " DOSBox " program
|
||||||
|
.BR IPXNET ". For help on the IPX networking from inside " DOSBox ", type"
|
||||||
|
.BR "IPXNET HELP" " and the program will list out the commands and relevant documentation."
|
||||||
|
.TP
|
||||||
|
.RB "Read the " README " of " DOSBox " for the full and correct syntax."
|
||||||
|
.RE
|
||||||
.SH FILES
|
.SH FILES
|
||||||
Configuration and language files use a format similar to Windows .ini files. If a file named
|
Configuration and language files use a format similar to Windows .ini files. If a file named
|
||||||
.BR dosbox.conf " is found in the current directory, it will be automatically loaded."
|
.BR dosbox.conf " is found in the current directory, it will be automatically loaded."
|
||||||
@ -130,10 +172,18 @@ Configuration and language files use a format similar to Windows .ini files. If
|
|||||||
.TP 12m
|
.TP 12m
|
||||||
.IP ALT\-ENTER
|
.IP ALT\-ENTER
|
||||||
Go full screen and back.
|
Go full screen and back.
|
||||||
|
.IP CTRL\-F1
|
||||||
|
Start the keymapper.
|
||||||
|
.IP CTRL\-F4
|
||||||
|
Swap mounted disk-image (Only used with imgmount).
|
||||||
.IP CTRL\-F5
|
.IP CTRL\-F5
|
||||||
Save a screenshot.
|
Save a screenshot.
|
||||||
.IP CTRL\-F6
|
.IP CTRL\-F6
|
||||||
Start/Stop recording sound output to a wave file.
|
Start/Stop recording sound output to a wave file.
|
||||||
|
.IP CTRL\-ALT\-F7
|
||||||
|
Start/Stop recording of OPL commands.
|
||||||
|
.IP CTRL\-ALT\-F8
|
||||||
|
Start/Stop the recording of raw MIDI commands.
|
||||||
.IP CTRL\-F7
|
.IP CTRL\-F7
|
||||||
Decrease frameskip.
|
Decrease frameskip.
|
||||||
.IP CTRL\-F8
|
.IP CTRL\-F8
|
||||||
@ -147,8 +197,9 @@ Slow down emulation (Increase DOSBox Cycles).
|
|||||||
.IP CTRL\-F12
|
.IP CTRL\-F12
|
||||||
Speed up emulation (Decrease DOSBox Cycles).
|
Speed up emulation (Decrease DOSBox Cycles).
|
||||||
.PP
|
.PP
|
||||||
.B "Note: "
|
These are the default keybindings. They can be changed in the keymapper.
|
||||||
Once you increase your DOSBox cycles beyond your computer's maximum
|
.PP
|
||||||
|
.BR "Note: " "Once you increase your " DOSBox " cycles beyond your computer's maximum
|
||||||
capacity, it will produce the same effect as slowing down the emulation.
|
capacity, it will produce the same effect as slowing down the emulation.
|
||||||
This maximum will vary from computer to computer, there is no standard.
|
This maximum will vary from computer to computer, there is no standard.
|
||||||
.SH "SYSTEM REQUIREMENTS"
|
.SH "SYSTEM REQUIREMENTS"
|
||||||
|
@ -12,8 +12,11 @@ fpu.h \
|
|||||||
hardware.h \
|
hardware.h \
|
||||||
inout.h \
|
inout.h \
|
||||||
joystick.h \
|
joystick.h \
|
||||||
|
ipx.h \
|
||||||
|
ipxserver.h \
|
||||||
keyboard.h \
|
keyboard.h \
|
||||||
logging.h \
|
logging.h \
|
||||||
|
mapper.h \
|
||||||
mem.h \
|
mem.h \
|
||||||
mixer.h \
|
mixer.h \
|
||||||
modules.h \
|
modules.h \
|
||||||
|
@ -143,8 +143,11 @@ fpu.h \
|
|||||||
hardware.h \
|
hardware.h \
|
||||||
inout.h \
|
inout.h \
|
||||||
joystick.h \
|
joystick.h \
|
||||||
|
ipx.h \
|
||||||
|
ipxserver.h \
|
||||||
keyboard.h \
|
keyboard.h \
|
||||||
logging.h \
|
logging.h \
|
||||||
|
mapper.h \
|
||||||
mem.h \
|
mem.h \
|
||||||
mixer.h \
|
mixer.h \
|
||||||
modules.h \
|
modules.h \
|
||||||
|
@ -9,13 +9,16 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef _BIOS_H_
|
||||||
|
#define _BIOS_H_
|
||||||
|
|
||||||
#define BIOS_BASE_ADDRESS_COM1 0x400
|
#define BIOS_BASE_ADDRESS_COM1 0x400
|
||||||
#define BIOS_BASE_ADDRESS_COM2 0x402
|
#define BIOS_BASE_ADDRESS_COM2 0x402
|
||||||
#define BIOS_BASE_ADDRESS_COM3 0x404
|
#define BIOS_BASE_ADDRESS_COM3 0x404
|
||||||
@ -88,6 +91,8 @@
|
|||||||
#define BIOS_WAIT_FLAG_POINTER 0x498
|
#define BIOS_WAIT_FLAG_POINTER 0x498
|
||||||
#define BIOS_WAIT_FLAG_COUNT 0x49c
|
#define BIOS_WAIT_FLAG_COUNT 0x49c
|
||||||
#define BIOS_WAIT_FLAG_ACTIVE 0x4a0
|
#define BIOS_WAIT_FLAG_ACTIVE 0x4a0
|
||||||
|
#define BIOS_WAIT_FLAG_TEMP 0x4a1
|
||||||
|
|
||||||
|
|
||||||
#define BIOS_PRINT_SCREEN_FLAG 0x500
|
#define BIOS_PRINT_SCREEN_FLAG 0x500
|
||||||
|
|
||||||
@ -96,23 +101,57 @@
|
|||||||
/* The Section handling Bios Disk Access */
|
/* The Section handling Bios Disk Access */
|
||||||
#define BIOS_MAX_DISK 10
|
#define BIOS_MAX_DISK 10
|
||||||
|
|
||||||
class BIOS_Disk {
|
struct diskGeo {
|
||||||
public:
|
Bit32u ksize; /* Size in kilobytes */
|
||||||
virtual Bit8u Read_Sector(Bit8u * count,Bit8u head,Bit16u cylinder,Bit16u sector,Bit8u * data)=0;
|
Bit16u secttrack; /* Sectors per track */
|
||||||
virtual Bit8u Write_Sector(Bit8u * count,Bit8u head,Bit16u cylinder,Bit16u sector,Bit8u * data)=0;
|
Bit16u headscyl; /* Heads per cylinder */
|
||||||
|
Bit16u cylcount; /* Cylinders per side */
|
||||||
|
Bit16u biosval; /* Type to return from BIOS */
|
||||||
};
|
};
|
||||||
|
|
||||||
class imageDisk : public BIOS_Disk {
|
extern diskGeo DiskGeometryList[];
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "mem.h"
|
||||||
|
#include "dos_inc.h"
|
||||||
|
|
||||||
|
class imageDisk {
|
||||||
public:
|
public:
|
||||||
Bit8u Read_Sector(Bit8u * count,Bit8u head,Bit16u cylinder,Bit16u sector,Bit8u * data);
|
Bit8u Read_Sector(Bit32u head,Bit32u cylinder,Bit32u sector,void * data);
|
||||||
Bit8u Write_Sector(Bit8u * count,Bit8u head,Bit16u cylinder,Bit16u sector,Bit8u * data);
|
Bit8u Write_Sector(Bit32u head,Bit32u cylinder,Bit32u sector,void * data);
|
||||||
imageDisk(char * file);
|
Bit8u Read_AbsoluteSector(Bit32u sectnum, void * data);
|
||||||
private:
|
Bit8u Write_AbsoluteSector(Bit32u sectnum, void * data);
|
||||||
Bit16u sector_size;
|
|
||||||
Bit16u heads,cylinders,sectors;
|
void Set_Geometry(Bit32u setHeads, Bit32u setCyl, Bit32u setSect, Bit32u setSectSize);
|
||||||
Bit8u * image;
|
void Get_Geometry(Bit32u * getHeads, Bit32u *getCyl, Bit32u *getSect, Bit32u *getSectSize);
|
||||||
|
Bit8u GetBiosType(void);
|
||||||
|
Bit32u getSectSize(void);
|
||||||
|
imageDisk(FILE *imgFile, Bit8u *imgName, Bit32u imgSizeK, bool isHardDisk);
|
||||||
|
~imageDisk() { if(diskimg != NULL) { fclose(diskimg); } };
|
||||||
|
|
||||||
|
bool hardDrive;
|
||||||
|
bool active;
|
||||||
|
FILE *diskimg;
|
||||||
|
Bit8u diskname[512];
|
||||||
|
Bit8u floppytype;
|
||||||
|
|
||||||
|
Bit32u sector_size;
|
||||||
|
Bit32u heads,cylinders,sectors;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void updateDPT(void);
|
||||||
|
|
||||||
|
#define MAX_HDD_IMAGES 2
|
||||||
|
|
||||||
|
extern imageDisk *imageDiskList[2 + MAX_HDD_IMAGES];
|
||||||
|
extern imageDisk *diskSwap[20];
|
||||||
|
extern Bits swapPosition;
|
||||||
|
extern Bit16u imgDTASeg; /* Real memory location of temporary DTA pointer for fat image disk access */
|
||||||
|
extern RealPt imgDTAPtr; /* Real memory location of temporary DTA pointer for fat image disk access */
|
||||||
|
extern DOS_DTA *imgDTA;
|
||||||
|
|
||||||
|
void swapInDisks(void);
|
||||||
|
void swapInNextDisk(void);
|
||||||
|
|
||||||
void BIOS_ZeroExtendedSize(void);
|
void BIOS_ZeroExtendedSize(void);
|
||||||
void char_out(Bit8u chr,Bit32u att,Bit8u page);
|
void char_out(Bit8u chr,Bit32u att,Bit8u page);
|
||||||
@ -123,4 +162,4 @@ void INT2F_StartUp(void);
|
|||||||
void INT33_StartUp(void);
|
void INT33_StartUp(void);
|
||||||
void INT13_StartUp(void);
|
void INT13_StartUp(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
@ -35,6 +35,7 @@ extern CPU_Decoder * cpudecoder;
|
|||||||
|
|
||||||
Bits CPU_Core_Normal_Run(void);
|
Bits CPU_Core_Normal_Run(void);
|
||||||
Bits CPU_Core_Normal_Trap_Run(void);
|
Bits CPU_Core_Normal_Trap_Run(void);
|
||||||
|
Bits CPU_Core_Simple_Run(void);
|
||||||
Bits CPU_Core_Full_Run(void);
|
Bits CPU_Core_Full_Run(void);
|
||||||
Bits CPU_Core_Dyn_X86_Run(void);
|
Bits CPU_Core_Dyn_X86_Run(void);
|
||||||
|
|
||||||
@ -52,7 +53,6 @@ void CPU_SLDT(Bitu & selector);
|
|||||||
void CPU_SIDT(Bitu & limit,Bitu & base);
|
void CPU_SIDT(Bitu & limit,Bitu & base);
|
||||||
void CPU_SGDT(Bitu & limit,Bitu & base);
|
void CPU_SGDT(Bitu & limit,Bitu & base);
|
||||||
|
|
||||||
|
|
||||||
void CPU_ARPL(Bitu & dest_sel,Bitu src_sel);
|
void CPU_ARPL(Bitu & dest_sel,Bitu src_sel);
|
||||||
void CPU_LAR(Bitu selector,Bitu & ar);
|
void CPU_LAR(Bitu selector,Bitu & ar);
|
||||||
void CPU_LSL(Bitu selector,Bitu & limit);
|
void CPU_LSL(Bitu selector,Bitu & limit);
|
||||||
@ -61,35 +61,44 @@ bool CPU_SET_CRX(Bitu cr,Bitu value);
|
|||||||
Bitu CPU_GET_CRX(Bitu cr);
|
Bitu CPU_GET_CRX(Bitu cr);
|
||||||
|
|
||||||
void CPU_SMSW(Bitu & word);
|
void CPU_SMSW(Bitu & word);
|
||||||
bool CPU_LMSW(Bitu word);
|
Bitu CPU_LMSW(Bitu word);
|
||||||
|
|
||||||
void CPU_VERR(Bitu selector);
|
void CPU_VERR(Bitu selector);
|
||||||
void CPU_VERW(Bitu selector);
|
void CPU_VERW(Bitu selector);
|
||||||
|
|
||||||
void CPU_JMP(bool use32,Bitu selector,Bitu offset,Bitu opLen=0);
|
void CPU_JMP(bool use32,Bitu selector,Bitu offset,Bitu oldeip);
|
||||||
void CPU_CALL(bool use32,Bitu selector,Bitu offset,Bitu opLen=0);
|
void CPU_CALL(bool use32,Bitu selector,Bitu offset,Bitu oldeip);
|
||||||
void CPU_RET(bool use32,Bitu bytes,Bitu opLen=0);
|
void CPU_RET(bool use32,Bitu bytes,Bitu oldeip);
|
||||||
|
void CPU_IRET(bool use32,Bitu oldeip);
|
||||||
|
void CPU_HLT(Bitu oldeip);
|
||||||
|
|
||||||
|
bool CPU_POPF(Bitu use32);
|
||||||
|
bool CPU_PUSHF(Bitu use32);
|
||||||
|
bool CPU_CLI(void);
|
||||||
|
bool CPU_STI(void);
|
||||||
|
|
||||||
|
bool CPU_IO_Exception(Bitu port,Bitu size);
|
||||||
|
void CPU_RunException(void);
|
||||||
|
|
||||||
|
void CPU_ENTER(bool use32,Bitu bytes,Bitu level);
|
||||||
|
|
||||||
#define CPU_INT_SOFTWARE 0x1
|
#define CPU_INT_SOFTWARE 0x1
|
||||||
#define CPU_INT_EXCEPTION 0x2
|
#define CPU_INT_EXCEPTION 0x2
|
||||||
#define CPU_INT_HAS_ERROR 0x4
|
#define CPU_INT_HAS_ERROR 0x4
|
||||||
|
|
||||||
|
void CPU_Interrupt(Bitu num,Bitu type,Bitu oldeip);
|
||||||
void CPU_Interrupt(Bitu num,Bitu type,Bitu opLen=0);
|
|
||||||
INLINE void CPU_HW_Interrupt(Bitu num) {
|
INLINE void CPU_HW_Interrupt(Bitu num) {
|
||||||
CPU_Interrupt(num,0);
|
CPU_Interrupt(num,0,reg_eip);
|
||||||
}
|
}
|
||||||
INLINE void CPU_SW_Interrupt(Bitu num,Bitu OpLen) {
|
INLINE void CPU_SW_Interrupt(Bitu num,Bitu oldeip) {
|
||||||
CPU_Interrupt(num,CPU_INT_SOFTWARE,OpLen);
|
CPU_Interrupt(num,CPU_INT_SOFTWARE,oldeip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CPU_PrepareException(Bitu which,Bitu error);
|
||||||
void CPU_Exception(Bitu which,Bitu error=0);
|
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);
|
bool CPU_SetSegGeneral(SegNames seg,Bitu value);
|
||||||
void CPU_HLT(Bitu opLen);
|
bool CPU_PopSeg(SegNames seg,bool use32);
|
||||||
|
|
||||||
void CPU_CPUID(void);
|
void CPU_CPUID(void);
|
||||||
Bitu CPU_Pop16(void);
|
Bitu CPU_Pop16(void);
|
||||||
@ -407,5 +416,6 @@ INLINE void CPU_SetFlagsw(Bitu word) {
|
|||||||
CPU_SetFlags(word,mask);
|
CPU_SetFlags(word,mask);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -9,14 +9,14 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: cross.h,v 1.7 2004/02/02 19:22:23 qbix79 Exp $ */
|
/* $Id: cross.h,v 1.11 2004/09/16 21:46:03 qbix79 Exp $ */
|
||||||
|
|
||||||
#ifndef _CROSS_H
|
#ifndef _CROSS_H
|
||||||
#define _CROSS_H
|
#define _CROSS_H
|
||||||
@ -29,6 +29,8 @@
|
|||||||
#include <direct.h>
|
#include <direct.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#define LONGTYPE(a) a##i64
|
#define LONGTYPE(a) a##i64
|
||||||
|
#define snprintf _snprintf
|
||||||
|
#define vsnprintf _vsnprintf
|
||||||
#else /* LINUX / GCC */
|
#else /* LINUX / GCC */
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -39,7 +41,7 @@
|
|||||||
|
|
||||||
|
|
||||||
#if defined (WIN32) /* Win 32 */
|
#if defined (WIN32) /* Win 32 */
|
||||||
#define CROSS_FILENAME(blah) {if(blah && *blah && (blah[strlen(blah)-1] == '\\')) strcat(blah,".");}
|
#define CROSS_FILENAME(blah)
|
||||||
#define CROSS_FILESPLIT '\\'
|
#define CROSS_FILESPLIT '\\'
|
||||||
#define F_OK 0
|
#define F_OK 0
|
||||||
#else
|
#else
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
|
184
include/dma.h
184
include/dma.h
@ -9,187 +9,85 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: dma.h,v 1.9 2004/01/10 14:03:33 qbix79 Exp $ */
|
/* $Id: dma.h,v 1.12 2004/08/04 09:12:50 qbix79 Exp $ */
|
||||||
|
|
||||||
#ifndef __DMA_H
|
#ifndef __DMA_H
|
||||||
#define __DMA_H
|
#define __DMA_H
|
||||||
|
|
||||||
#include "mem.h"
|
enum DMAEvent {
|
||||||
|
DMA_REACHED_TC,
|
||||||
|
DMA_MASKED,
|
||||||
|
DMA_UNMASKED,
|
||||||
|
DMA_TRANSFEREND
|
||||||
|
};
|
||||||
|
|
||||||
#define DMA_MODE_DEMAND 0
|
class DmaChannel;
|
||||||
#define DMA_MODE_SINGLE 1
|
typedef void (* DMA_CallBack)(DmaChannel * chan,DMAEvent event);
|
||||||
#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 {
|
class DmaController {
|
||||||
public:
|
public:
|
||||||
bool flipflop;
|
bool flipflop;
|
||||||
Bit8u ctrlnum;
|
Bit8u ctrlnum;
|
||||||
|
Bit8u chanbase;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
DmaController(Bit8u num) {
|
DmaController(Bit8u num) {
|
||||||
int i;
|
flipflop = false;
|
||||||
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;
|
ctrlnum = num;
|
||||||
|
chanbase = num * 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bit16u portRead(Bit32u port, bool eightbit);
|
|
||||||
void portWrite(Bit32u port, Bit16u val, bool eightbit);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class DmaChannel {
|
class DmaChannel {
|
||||||
public:
|
public:
|
||||||
|
Bit32u pagebase;
|
||||||
Bit8u channum;
|
|
||||||
Bit16u baseaddr;
|
Bit16u baseaddr;
|
||||||
Bit16u current_addr;
|
Bit16u curraddr;
|
||||||
Bit16u pageaddr;
|
Bit16u basecnt;
|
||||||
PhysPt physaddr;
|
Bit16u currcnt;
|
||||||
PhysPt curraddr;
|
Bit8u channum;
|
||||||
Bit32s transcnt;
|
Bit8u pagenum;
|
||||||
Bit32s currcnt;
|
Bit8u DMA16;
|
||||||
DmaController *myController;
|
bool increment;
|
||||||
bool DMA16;
|
|
||||||
bool addr_changed;
|
|
||||||
public:
|
|
||||||
Bit8u dmamode;
|
|
||||||
bool dir;
|
|
||||||
bool autoinit;
|
bool autoinit;
|
||||||
Bit8u trantype;
|
Bit8u trantype;
|
||||||
bool masked;
|
bool masked;
|
||||||
bool enabled;
|
bool tcount;
|
||||||
DMA_EnableCallBack enable_callback;
|
DMA_CallBack callback;
|
||||||
DMA_NewCallBack newcallback;
|
|
||||||
|
|
||||||
DmaChannel(Bit8u num, DmaController *useController, bool sb) {
|
DmaChannel(Bit8u num, bool dma16);
|
||||||
int i;
|
void DoCallBack(DMAEvent event) {
|
||||||
masked = true;
|
if (callback) (*callback)(this,event);
|
||||||
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;
|
void SetMask(bool _mask) {
|
||||||
channum = num;
|
masked=_mask;
|
||||||
DMA16 = sb;
|
DoCallBack(masked ? DMA_MASKED : DMA_UNMASKED);
|
||||||
baseaddr = 0;
|
|
||||||
pageaddr = 0;
|
|
||||||
physaddr = 0;
|
|
||||||
curraddr = 0;
|
|
||||||
transcnt = 0;
|
|
||||||
currcnt = 0;
|
|
||||||
dir = false;
|
|
||||||
autoinit = false;
|
|
||||||
}
|
}
|
||||||
|
void Register_Callback(DMA_CallBack _cb) {
|
||||||
void RegisterCallback(DMA_NewCallBack useCallBack) { newcallback = useCallBack; }
|
callback = _cb;
|
||||||
|
SetMask(masked);
|
||||||
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 ReachedTC(void) {
|
||||||
void MakeCallback(bool tc) {
|
tcount=true;
|
||||||
if (newcallback != NULL) {
|
DoCallBack(DMA_REACHED_TC);
|
||||||
if(tc) {
|
|
||||||
(*newcallback)(this, true);
|
|
||||||
} else {
|
|
||||||
if ((enabled) && (!masked) && (transcnt!=0)) {
|
|
||||||
(*newcallback)(this, false);
|
|
||||||
}
|
}
|
||||||
|
void SetPage(Bit8u val) {
|
||||||
|
pagenum=val;
|
||||||
|
pagebase=(pagenum >> DMA16) << (16+DMA16);
|
||||||
}
|
}
|
||||||
|
Bitu Read(Bitu size, Bit8u * buffer);
|
||||||
}
|
Bitu Write(Bitu size, Bit8u * buffer);
|
||||||
}
|
|
||||||
|
|
||||||
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 DmaChannel *DmaChannels[8];
|
||||||
extern DmaController *DmaControllers[2];
|
extern DmaController *DmaControllers[2];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,13 +9,15 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* $Id: dos_inc.h,v 1.48 2004/08/04 09:12:50 qbix79 Exp $ */
|
||||||
|
|
||||||
#ifndef DOS_H_
|
#ifndef DOS_H_
|
||||||
#define DOS_H_
|
#define DOS_H_
|
||||||
|
|
||||||
@ -43,27 +45,25 @@ struct DOS_Version {
|
|||||||
Bit8u major,minor,revision;
|
Bit8u major,minor,revision;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DOS_Block {
|
|
||||||
DOS_Date date;
|
|
||||||
DOS_Version version;
|
|
||||||
Bit16u firstMCB;
|
|
||||||
Bit16u errorcode;
|
|
||||||
Bit16u psp;
|
|
||||||
Bit16u env;
|
|
||||||
RealPt cpmentry;
|
|
||||||
RealPt dta;
|
|
||||||
Bit8u return_code,return_mode;
|
|
||||||
|
|
||||||
Bit8u current_drive;
|
#ifdef _MSC_VER
|
||||||
bool verify;
|
#pragma pack (1)
|
||||||
bool breakcheck;
|
#endif
|
||||||
bool echo; // if set to true dev_con::read will echo input
|
union bootSector {
|
||||||
struct {
|
struct entries {
|
||||||
RealPt indosflag;
|
Bit8u jump[3];
|
||||||
RealPt mediaid;
|
Bit8u oem_name[8];
|
||||||
RealPt tempdta;
|
Bit16u bytesect;
|
||||||
} tables;
|
Bit8u sectclust;
|
||||||
};
|
Bit16u reserve_sect;
|
||||||
|
Bit8u misc[496];
|
||||||
|
} bootdata;
|
||||||
|
Bit8u rawdata[512];
|
||||||
|
} GCC_ATTRIBUTE(packed);
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma pack ()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
enum { MCB_FREE=0x0000,MCB_DOS=0x0008 };
|
enum { MCB_FREE=0x0000,MCB_DOS=0x0008 };
|
||||||
enum { RETURN_EXIT=0,RETURN_CTRLC=1,RETURN_ABORT=2,RETURN_TSR=3};
|
enum { RETURN_EXIT=0,RETURN_CTRLC=1,RETURN_ABORT=2,RETURN_TSR=3};
|
||||||
@ -72,7 +72,7 @@ enum { RETURN_EXIT=0,RETURN_CTRLC=1,RETURN_ABORT=2,RETURN_TSR=3};
|
|||||||
#define DOS_DRIVES 26
|
#define DOS_DRIVES 26
|
||||||
|
|
||||||
/* internal Dos Tables */
|
/* internal Dos Tables */
|
||||||
extern DOS_Block dos;
|
|
||||||
extern DOS_File * Files[DOS_FILES];
|
extern DOS_File * Files[DOS_FILES];
|
||||||
extern DOS_Drive * Drives[DOS_DRIVES];
|
extern DOS_Drive * Drives[DOS_DRIVES];
|
||||||
extern Bit8u dos_copybuf[0x10000];
|
extern Bit8u dos_copybuf[0x10000];
|
||||||
@ -100,7 +100,7 @@ bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry);
|
|||||||
bool DOS_OpenFileExtended(char *name, Bit16u flags, Bit16u createAttr, Bit16u action, Bit16u *entry, Bit16u* status);
|
bool DOS_OpenFileExtended(char *name, Bit16u flags, Bit16u createAttr, Bit16u action, Bit16u *entry, Bit16u* status);
|
||||||
bool DOS_CreateFile(char * name,Bit16u attribute,Bit16u * entry);
|
bool DOS_CreateFile(char * name,Bit16u attribute,Bit16u * entry);
|
||||||
bool DOS_UnlinkFile(char * name);
|
bool DOS_UnlinkFile(char * name);
|
||||||
bool DOS_FindFirst(char *search,Bit16u attr);
|
bool DOS_FindFirst(char *search,Bit16u attr,bool fcb_findfirst=false);
|
||||||
bool DOS_FindNext(void);
|
bool DOS_FindNext(void);
|
||||||
bool DOS_Canonicalize(char * name,char * big);
|
bool DOS_Canonicalize(char * name,char * big);
|
||||||
bool DOS_CreateTempFile(char * name,Bit16u * entry);
|
bool DOS_CreateTempFile(char * name,Bit16u * entry);
|
||||||
@ -208,30 +208,26 @@ INLINE Bit16u DOS_PackDate(Bit16u year,Bit16u mon,Bit16u day) {
|
|||||||
|
|
||||||
|
|
||||||
/* Remains some classes used to access certain things */
|
/* Remains some classes used to access certain things */
|
||||||
|
#define sOffset(s,m) ((char*)&(((s*)NULL)->m)-(char*)NULL)
|
||||||
#define sGet(s,m) GetIt(((s *)0)->m,(PhysPt)&(((s *)0)->m))
|
#define sGet(s,m) GetIt(sizeof(((s *)&pt)->m),(PhysPt)sOffset(s,m))
|
||||||
#define sSave(s,m,val) SaveIt(((s *)0)->m,(PhysPt)&(((s *)0)->m),val)
|
#define sSave(s,m,val) SaveIt(sizeof(((s *)&pt)->m),(PhysPt)sOffset(s,m),val)
|
||||||
|
|
||||||
|
|
||||||
class MemStruct {
|
class MemStruct {
|
||||||
public:
|
public:
|
||||||
INLINE Bit8u GetIt(Bit8u&,PhysPt addr) {
|
INLINE Bitu GetIt(Bitu size,PhysPt addr) {
|
||||||
return mem_readb(pt+addr);
|
switch (size) {
|
||||||
|
case 1:return mem_readb(pt+addr);
|
||||||
|
case 2:return mem_readw(pt+addr);
|
||||||
|
case 4:return mem_readd(pt+addr);
|
||||||
}
|
}
|
||||||
INLINE Bit16u GetIt(Bit16u&,PhysPt addr) {
|
return 0;
|
||||||
return mem_readw(pt+addr);
|
|
||||||
}
|
}
|
||||||
INLINE Bit32u GetIt(Bit32u&,PhysPt addr) {
|
INLINE void SaveIt(Bitu size,PhysPt addr,Bitu val) {
|
||||||
return mem_readd(pt+addr);
|
switch (size) {
|
||||||
|
case 1:mem_writeb(pt+addr,val);break;
|
||||||
|
case 2:mem_writew(pt+addr,val);break;
|
||||||
|
case 4:mem_writed(pt+addr,val);break;
|
||||||
}
|
}
|
||||||
INLINE void SaveIt(Bit8u&,PhysPt addr,Bit8u val) {
|
|
||||||
mem_writeb(pt+addr,val);
|
|
||||||
}
|
|
||||||
INLINE void SaveIt(Bit16u&,PhysPt addr,Bit16u val) {
|
|
||||||
mem_writew(pt+addr,val);
|
|
||||||
}
|
|
||||||
INLINE void SaveIt(Bit32u&,PhysPt addr,Bit32u val) {
|
|
||||||
mem_writed(pt+addr,val);
|
|
||||||
}
|
}
|
||||||
INLINE void SetPt(Bit16u seg) { pt=PhysMake(seg,0);}
|
INLINE void SetPt(Bit16u seg) { pt=PhysMake(seg,0);}
|
||||||
INLINE void SetPt(Bit16u seg,Bit16u off) { pt=PhysMake(seg,off);}
|
INLINE void SetPt(Bit16u seg,Bit16u off) { pt=PhysMake(seg,off);}
|
||||||
@ -252,8 +248,6 @@ public:
|
|||||||
void RestoreVectors (void);
|
void RestoreVectors (void);
|
||||||
void SetSize (Bit16u size) { sSave(sPSP,next_seg,size); };
|
void SetSize (Bit16u size) { sSave(sPSP,next_seg,size); };
|
||||||
Bit16u GetSize (void) { return sGet(sPSP,next_seg); };
|
Bit16u GetSize (void) { return sGet(sPSP,next_seg); };
|
||||||
void SetDTA (RealPt ptdta) { sSave(sPSP,dta,ptdta); };
|
|
||||||
RealPt GetDTA (void) { return sGet(sPSP,dta); };
|
|
||||||
void SetEnvironment (Bit16u envseg) { sSave(sPSP,environment,envseg); };
|
void SetEnvironment (Bit16u envseg) { sSave(sPSP,environment,envseg); };
|
||||||
Bit16u GetEnvironment (void) { return sGet(sPSP,environment); };
|
Bit16u GetEnvironment (void) { return sGet(sPSP,environment); };
|
||||||
Bit16u GetSegment (void) { return seg; };
|
Bit16u GetSegment (void) { return seg; };
|
||||||
@ -291,8 +285,11 @@ private:
|
|||||||
Bit16u max_files; /* Maximum open files */
|
Bit16u max_files; /* Maximum open files */
|
||||||
RealPt file_table; /* Pointer to File Table PSP:0x18 */
|
RealPt file_table; /* Pointer to File Table PSP:0x18 */
|
||||||
RealPt prev_psp; /* Pointer to previous PSP */
|
RealPt prev_psp; /* Pointer to previous PSP */
|
||||||
RealPt dta; /* Pointer to current Process DTA */
|
Bit8u interim_flag;
|
||||||
Bit8u fill_2[16]; /* Lot's of unused stuff i can't care aboue */
|
Bit8u truename_flag;
|
||||||
|
Bit16u nn_flags;
|
||||||
|
Bit16u dos_version;
|
||||||
|
Bit8u fill_2[14]; /* Lot's of unused stuff i can't care aboue */
|
||||||
Bit8u service[3]; /* INT 0x21 Service call int 0x21;retf; */
|
Bit8u service[3]; /* INT 0x21 Service call int 0x21;retf; */
|
||||||
Bit8u fill_3[9]; /* This has some blocks with FCB info */
|
Bit8u fill_3[9]; /* This has some blocks with FCB info */
|
||||||
Bit8u fcb1[16]; /* first FCB */
|
Bit8u fcb1[16]; /* first FCB */
|
||||||
@ -343,25 +340,50 @@ public:
|
|||||||
void SetFirstMCB(Bit16u _first_mcb);
|
void SetFirstMCB(Bit16u _first_mcb);
|
||||||
void SetfirstFileTable(RealPt _first_table);
|
void SetfirstFileTable(RealPt _first_table);
|
||||||
void SetBuffers(Bit16u x,Bit16u y);
|
void SetBuffers(Bit16u x,Bit16u y);
|
||||||
|
void SetCurDirStruct(Bit32u _curdirstruct);
|
||||||
|
void SetFCBTable(Bit32u _fcbtable);
|
||||||
|
void SetDeviceChainStart(Bit32u _devchain);
|
||||||
|
void SetDiskInfoBuffer(Bit32u _dinfobuf);
|
||||||
RealPt GetPointer (void);
|
RealPt GetPointer (void);
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
#endif
|
#endif
|
||||||
struct sDIB {
|
struct sDIB {
|
||||||
Bit8u stuff1[22]; // -0x18 some stuff, hopefully never used....
|
Bit16u regCXfrom5e; // -0x18 CX from last int21/ah=5e
|
||||||
Bit16u firstMCB; // -0x2 first memory control block
|
Bit16u countLRUcache; // -0x16 LRU counter for FCB caching
|
||||||
|
Bit16u countLRUopens; // -0x14 LRU counter for FCB openings
|
||||||
|
Bit8u stuff[6]; // -0x12 some stuff, hopefully never used....
|
||||||
|
Bit16u sharingCount; // -0x0c sharing retry count
|
||||||
|
Bit16u sharingDelay; // -0x0a sharing retry delay
|
||||||
|
RealPt diskBufPtr; // -0x08 pointer to disk buffer
|
||||||
|
Bit16u ptrCONinput; // -0x04 pointer to con input
|
||||||
|
Bit16u firstMCB; // -0x02 first memory control block
|
||||||
RealPt firstDPB; // 0x00 first drive parameter block
|
RealPt firstDPB; // 0x00 first drive parameter block
|
||||||
RealPt firstFileTable; // 0x04 first system file table
|
RealPt firstFileTable; // 0x04 first system file table
|
||||||
RealPt activeClock; // 0x08 active clock device header
|
RealPt activeClock; // 0x08 active clock device header
|
||||||
RealPt activeCon; // 0x0c active console device header
|
RealPt activeCon; // 0x0c active console device header
|
||||||
Bit16u maxSectorLength; // 0x10 maximum bytes per sector of any block device;
|
Bit16u maxSectorLength; // 0x10 maximum bytes per sector of any block device;
|
||||||
RealPt discInfoBuffer; // 0x12 pointer to disc info buffer
|
RealPt diskInfoBuffer; // 0x12 pointer to disk info buffer
|
||||||
RealPt curDirStructure; // 0x16 pointer to current array of directory structure
|
RealPt curDirStructure; // 0x16 pointer to current array of directory structure
|
||||||
RealPt fcbTable; // 0x1a pointer to system FCB table
|
RealPt fcbTable; // 0x1a pointer to system FCB table
|
||||||
Bit8u stuff2[0x21]; // 0x1e more stuff
|
Bit16u protFCBs; // 0x1e protected fcbs
|
||||||
Bit16u buffers_x; // x in BUFFERS x,y
|
Bit8u blockDevices; // 0x20 installed block devices
|
||||||
Bit16u buffers_y; // y in BUFFERS x,y
|
Bit8u lastdrive; // 0x21 lastdrive
|
||||||
|
Bit32u nulNextDriver; // 0x22 NUL driver next pointer
|
||||||
|
Bit16u nulAttributes; // 0x26 NUL driver aattributes
|
||||||
|
Bit32u nulStrategy; // 0x28 NUL driver strategy routine
|
||||||
|
Bit8u nulString[8]; // 0x2c NUL driver name string
|
||||||
|
Bit8u joindedDrives; // 0x34 joined drives
|
||||||
|
Bit16u specialCodeSeg; // 0x35 special code segment
|
||||||
|
RealPt setverPtr; // 0x37 pointer to setver
|
||||||
|
Bit16u a20FixOfs; // 0x3b a20 fix routine offset
|
||||||
|
Bit16u pspLastIfHMA; // 0x3d psp of last program (if dos in hma)
|
||||||
|
Bit16u buffers_x; // 0x3f x in BUFFERS x,y
|
||||||
|
Bit16u buffers_y; // 0x41 y in BUFFERS x,y
|
||||||
|
Bit8u bootDrive; // 0x43 boot drive
|
||||||
|
Bit8u useDwordMov; // 0x44 use dword moves
|
||||||
|
Bit16u extendedSize; // 0x45 size of extended memory
|
||||||
// some more stuff, hopefully never used.
|
// some more stuff, hopefully never used.
|
||||||
} GCC_ATTRIBUTE(packed);
|
} GCC_ATTRIBUTE(packed);
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
@ -389,9 +411,9 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
struct sDTA {
|
struct sDTA {
|
||||||
Bit8u sdrive; /* The Drive the search is taking place */
|
Bit8u sdrive; /* The Drive the search is taking place */
|
||||||
Bit8u sattr; /* The Attributes that need to be found */
|
|
||||||
Bit8u sname[8]; /* The Search pattern for the filename */
|
Bit8u sname[8]; /* The Search pattern for the filename */
|
||||||
Bit8u sext[3]; /* The Search pattern for the extenstion */
|
Bit8u sext[3]; /* The Search pattern for the extenstion */
|
||||||
|
Bit8u sattr; /* The Attributes that need to be found */
|
||||||
Bit16u dirID; /* custom: dir-search ID for multiple searches at the same time */
|
Bit16u dirID; /* custom: dir-search ID for multiple searches at the same time */
|
||||||
Bit8u fill[6];
|
Bit8u fill[6];
|
||||||
Bit8u attr;
|
Bit8u attr;
|
||||||
@ -422,6 +444,8 @@ public:
|
|||||||
void SetRandom(Bit32u _random);
|
void SetRandom(Bit32u _random);
|
||||||
Bit8u GetDrive(void);
|
Bit8u GetDrive(void);
|
||||||
bool Extended(void);
|
bool Extended(void);
|
||||||
|
void GetAttr(Bit8u & attr);
|
||||||
|
void SetAttr(Bit8u attr);
|
||||||
private:
|
private:
|
||||||
bool extended;
|
bool extended;
|
||||||
PhysPt real_pt;
|
PhysPt real_pt;
|
||||||
@ -438,8 +462,11 @@ private:
|
|||||||
Bit16u date;
|
Bit16u date;
|
||||||
Bit16u time;
|
Bit16u time;
|
||||||
/* Reserved Block should be 8 bytes */
|
/* Reserved Block should be 8 bytes */
|
||||||
|
Bit8u sft_entries;
|
||||||
|
Bit8u share_attributes;
|
||||||
|
Bit8u extra_info;
|
||||||
Bit8u file_handle;
|
Bit8u file_handle;
|
||||||
Bit8u reserved[7];
|
Bit8u reserved[4];
|
||||||
/* end */
|
/* end */
|
||||||
Bit8u cur_rec; /* Current record in current block */
|
Bit8u cur_rec; /* Current record in current block */
|
||||||
Bit32u rndm; /* Current relative record number */
|
Bit32u rndm; /* Current relative record number */
|
||||||
@ -476,10 +503,78 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
extern DOS_InfoBlock dos_infoblock;;
|
extern Bit16u sdaseg;
|
||||||
|
#define DOS_SDA_SEG sdaseg
|
||||||
|
#define DOS_SDA_OFS 0
|
||||||
|
|
||||||
|
|
||||||
|
class DOS_SDA : public MemStruct {
|
||||||
|
public:
|
||||||
|
DOS_SDA(Bit16u _seg,Bit16u _offs) { SetPt(_seg,_offs); }
|
||||||
|
void Init();
|
||||||
|
void SetDrive(Bit8u _drive) { sSave(sSDA,current_drive, _drive); }
|
||||||
|
void SetDTA(Bit32u _dta) { sSave(sSDA,current_dta, _dta); }
|
||||||
|
void SetPSP(Bit16u _psp) { sSave(sSDA,current_psp, _psp); }
|
||||||
|
Bit8u GetDrive(void) { return sGet(sSDA,current_drive); }
|
||||||
|
Bit16u GetPSP(void) { return sGet(sSDA,current_psp); }
|
||||||
|
Bit32u GetDTA(void) { return sGet(sSDA,current_dta); }
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma pack (1)
|
||||||
|
#endif
|
||||||
|
struct sSDA {
|
||||||
|
Bit8u crit_error_flag; /* 0x00 Critical Error Flag */
|
||||||
|
Bit8u inDOS_flag; /* 0x01 InDOS flag (count of active INT 21 calls) */
|
||||||
|
Bit8u drive_crit_error; /* 0x02 Drive on which current critical error occurred or FFh */
|
||||||
|
Bit8u locus_of_last_error; /* 0x03 locus of last error */
|
||||||
|
Bit16u extended_error_code; /* 0x04 extended error code of last error */
|
||||||
|
Bit8u suggested_action; /* 0x06 suggested action for last error */
|
||||||
|
Bit8u error_class; /* 0x07 class of last error*/
|
||||||
|
Bit32u last_error_pointer; /* 0x08 ES:DI pointer for last error */
|
||||||
|
Bit32u current_dta; /* 0x0C current DTA (Disk Transfer Address) */
|
||||||
|
Bit16u current_psp; /* 0x10 current PSP */
|
||||||
|
Bit16u sp_int_23; /* 0x12 stores SP across an INT 23 */
|
||||||
|
Bit16u return_code; /* 0x14 return code from last process termination (zerod after reading with AH=4Dh) */
|
||||||
|
Bit8u current_drive; /* 0x16 current drive */
|
||||||
|
Bit8u extended_break_flag; /* 0x17 extended break flag */
|
||||||
|
Bit8u fill[2]; /* 0x18 flag: code page switching || flag: copy of previous byte in case of INT 24 Abort*/
|
||||||
|
} GCC_ATTRIBUTE(packed);
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma pack()
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
extern DOS_InfoBlock dos_infoblock;
|
||||||
|
|
||||||
|
struct DOS_Block {
|
||||||
|
DOS_Date date;
|
||||||
|
DOS_Version version;
|
||||||
|
Bit16u firstMCB;
|
||||||
|
Bit16u errorcode;
|
||||||
|
Bit16u psp(){return DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).GetPSP();};
|
||||||
|
void psp(Bit16u _seg){ DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).SetPSP(_seg);};
|
||||||
|
Bit16u env;
|
||||||
|
RealPt cpmentry;
|
||||||
|
RealPt dta(){return DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).GetDTA();};
|
||||||
|
void dta(RealPt _dta){DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).SetDTA(_dta);};
|
||||||
|
Bit8u return_code,return_mode;
|
||||||
|
|
||||||
|
Bit8u current_drive;
|
||||||
|
bool verify;
|
||||||
|
bool breakcheck;
|
||||||
|
bool echo; // if set to true dev_con::read will echo input
|
||||||
|
struct {
|
||||||
|
RealPt mediaid;
|
||||||
|
RealPt tempdta;
|
||||||
|
RealPt dcbs;
|
||||||
|
} tables;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern DOS_Block dos;
|
||||||
|
|
||||||
INLINE Bit8u RealHandle(Bit16u handle) {
|
INLINE Bit8u RealHandle(Bit16u handle) {
|
||||||
DOS_PSP psp(dos.psp);
|
DOS_PSP psp(dos.psp());
|
||||||
return psp.GetFileHandle(handle);
|
return psp.GetFileHandle(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,14 +9,14 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: dos_system.h,v 1.20 2004/01/12 20:25:57 finsterr Exp $ */
|
/* $Id: dos_system.h,v 1.24 2004/08/04 09:12:50 qbix79 Exp $ */
|
||||||
|
|
||||||
#ifndef DOSSYSTEM_H_
|
#ifndef DOSSYSTEM_H_
|
||||||
#define DOSSYSTEM_H_
|
#define DOSSYSTEM_H_
|
||||||
@ -54,7 +54,7 @@ class DOS_DTA;
|
|||||||
class DOS_File {
|
class DOS_File {
|
||||||
public:
|
public:
|
||||||
DOS_File():flags(0) { name=0; refCtr = 0; };
|
DOS_File():flags(0) { name=0; refCtr = 0; };
|
||||||
virtual ~DOS_File(){};
|
virtual ~DOS_File(){if(name) delete [] name;};
|
||||||
virtual bool Read(Bit8u * data,Bit16u * size)=0;
|
virtual bool Read(Bit8u * data,Bit16u * size)=0;
|
||||||
virtual bool Write(Bit8u * data,Bit16u * size)=0;
|
virtual bool Write(Bit8u * data,Bit16u * size)=0;
|
||||||
virtual bool Seek(Bit32u * pos,Bit32u type)=0;
|
virtual bool Seek(Bit32u * pos,Bit32u type)=0;
|
||||||
@ -66,6 +66,7 @@ public:
|
|||||||
virtual bool IsName(const char* _name) { if (!name) return false; return strcmp(name,_name)==0; };
|
virtual bool IsName(const char* _name) { if (!name) return false; return strcmp(name,_name)==0; };
|
||||||
virtual void AddRef() { refCtr++; };
|
virtual void AddRef() { refCtr++; };
|
||||||
virtual Bits RemoveRef() { return --refCtr; };
|
virtual Bits RemoveRef() { return --refCtr; };
|
||||||
|
virtual bool UpdateDateTimeFromHost() { return true; }
|
||||||
Bit8u type;
|
Bit8u type;
|
||||||
Bit32u flags;
|
Bit32u flags;
|
||||||
Bit16u time;
|
Bit16u time;
|
||||||
@ -85,8 +86,8 @@ public:
|
|||||||
Bit8u fhandle;
|
Bit8u fhandle;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAX_OPENDIRS 16
|
#define MAX_OPENDIRS 2048
|
||||||
|
//Can be high as it's only storage (16 bit variable)
|
||||||
class DOS_Drive_Cache {
|
class DOS_Drive_Cache {
|
||||||
public:
|
public:
|
||||||
DOS_Drive_Cache (void);
|
DOS_Drive_Cache (void);
|
||||||
@ -104,7 +105,7 @@ public:
|
|||||||
char* GetExpandName (const char* path);
|
char* GetExpandName (const char* path);
|
||||||
bool GetShortName (const char* fullname, char* shortname);
|
bool GetShortName (const char* fullname, char* shortname);
|
||||||
|
|
||||||
bool FindFirst (char* path, Bitu dtaAddress, Bitu& id);
|
bool FindFirst (char* path, Bitu& id);
|
||||||
bool FindNext (Bitu id, char* &result);
|
bool FindNext (Bitu id, char* &result);
|
||||||
|
|
||||||
void CacheOut (const char* path, bool ignoreLastDir = false);
|
void CacheOut (const char* path, bool ignoreLastDir = false);
|
||||||
@ -119,21 +120,19 @@ public:
|
|||||||
public:
|
public:
|
||||||
CFileInfo(void) {
|
CFileInfo(void) {
|
||||||
orgname[0] = shortname[0] = 0;
|
orgname[0] = shortname[0] = 0;
|
||||||
nextEntry = shortNr = compareCount = 0;
|
nextEntry = shortNr = 0;
|
||||||
isDir = false;
|
isDir = false;
|
||||||
}
|
}
|
||||||
~CFileInfo(void) {
|
~CFileInfo(void) {
|
||||||
for (Bit32u i=0; i<fileList.size(); i++) delete fileList[i];
|
for (Bit32u i=0; i<fileList.size(); i++) delete fileList[i];
|
||||||
fileList.clear();
|
fileList.clear();
|
||||||
longNameList.clear();
|
longNameList.clear();
|
||||||
compareCount = 0;
|
|
||||||
};
|
};
|
||||||
char orgname [CROSS_LEN];
|
char orgname [CROSS_LEN];
|
||||||
char shortname [DOS_NAMELENGTH_ASCII];
|
char shortname [DOS_NAMELENGTH_ASCII];
|
||||||
bool isDir;
|
bool isDir;
|
||||||
Bitu nextEntry;
|
Bitu nextEntry;
|
||||||
Bitu shortNr;
|
Bitu shortNr;
|
||||||
Bitu compareCount;
|
|
||||||
// contents
|
// contents
|
||||||
std::vector<CFileInfo*> fileList;
|
std::vector<CFileInfo*> fileList;
|
||||||
std::vector<CFileInfo*> longNameList;
|
std::vector<CFileInfo*> longNameList;
|
||||||
@ -169,6 +168,7 @@ private:
|
|||||||
char dirSearchName [MAX_OPENDIRS];
|
char dirSearchName [MAX_OPENDIRS];
|
||||||
bool free [MAX_OPENDIRS];
|
bool free [MAX_OPENDIRS];
|
||||||
CFileInfo* dirFindFirst [MAX_OPENDIRS];
|
CFileInfo* dirFindFirst [MAX_OPENDIRS];
|
||||||
|
Bitu nextFreeFindFirst;
|
||||||
|
|
||||||
char label [CROSS_LEN];
|
char label [CROSS_LEN];
|
||||||
};
|
};
|
||||||
@ -217,7 +217,7 @@ public:
|
|||||||
virtual bool RemoveDir(char * _dir)=0;
|
virtual bool RemoveDir(char * _dir)=0;
|
||||||
virtual bool MakeDir(char * _dir)=0;
|
virtual bool MakeDir(char * _dir)=0;
|
||||||
virtual bool TestDir(char * _dir)=0;
|
virtual bool TestDir(char * _dir)=0;
|
||||||
virtual bool FindFirst(char * _dir,DOS_DTA & dta)=0;
|
virtual bool FindFirst(char * _dir,DOS_DTA & dta,bool fcb_findfirst=false)=0;
|
||||||
virtual bool FindNext(DOS_DTA & dta)=0;
|
virtual bool FindNext(DOS_DTA & dta)=0;
|
||||||
virtual bool GetFileAttr(char * name,Bit16u * attr)=0;
|
virtual bool GetFileAttr(char * name,Bit16u * attr)=0;
|
||||||
virtual bool Rename(char * oldname,char * newname)=0;
|
virtual bool Rename(char * oldname,char * newname)=0;
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
@ -24,25 +24,6 @@ void E_Exit(char * message,...);
|
|||||||
void MSG_Add(const char*,const char*); //add messages to the internal langaugefile
|
void MSG_Add(const char*,const char*); //add messages to the internal langaugefile
|
||||||
const char* MSG_Get(char const *); //get messages from the internal langaugafile
|
const char* MSG_Get(char const *); //get messages from the internal langaugafile
|
||||||
|
|
||||||
/* The internal types */
|
|
||||||
typedef unsigned char Bit8u;
|
|
||||||
typedef signed char Bit8s;
|
|
||||||
typedef unsigned short Bit16u;
|
|
||||||
typedef signed short Bit16s;
|
|
||||||
typedef unsigned long Bit32u;
|
|
||||||
typedef signed long Bit32s;
|
|
||||||
typedef double Real64;
|
|
||||||
#if defined(_MSC_VER)
|
|
||||||
typedef unsigned __int64 Bit64u;
|
|
||||||
typedef signed __int64 Bit64s;
|
|
||||||
#else
|
|
||||||
typedef unsigned long long Bit64u;
|
|
||||||
typedef signed long long Bit64s;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef unsigned int Bitu;
|
|
||||||
typedef signed int Bits;
|
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
@ -63,11 +44,11 @@ enum MachineType {
|
|||||||
MCH_HERC,
|
MCH_HERC,
|
||||||
MCH_CGA,
|
MCH_CGA,
|
||||||
MCH_TANDY,
|
MCH_TANDY,
|
||||||
MCH_VGA,
|
MCH_VGA
|
||||||
MCH_AUTO
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern MachineType machine;
|
extern MachineType machine;
|
||||||
|
extern bool SDLNetInited;
|
||||||
|
|
||||||
#ifndef __LOGGING_H_
|
#ifndef __LOGGING_H_
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
@ -19,7 +19,17 @@
|
|||||||
#ifndef _HARDWARE_H_
|
#ifndef _HARDWARE_H_
|
||||||
#define _HARDWARE_H_
|
#define _HARDWARE_H_
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
class Section;
|
||||||
|
enum OPL_Mode {
|
||||||
|
OPL_none,OPL_cms,OPL_opl2,OPL_dualopl2,OPL_opl3
|
||||||
|
};
|
||||||
|
|
||||||
|
void OPL_Init(Section* sec,Bitu base,OPL_Mode mode,Bitu rate);
|
||||||
|
void CMS_Init(Section* sec,Bitu base,Bitu rate);
|
||||||
|
extern Bit8u adlib_commandreg;
|
||||||
|
FILE * OpenCaptureFile(const char * type,const char * ext);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -9,37 +9,51 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef Bit8u (IO_ReadBHandler)(Bit32u port);
|
#define IO_MAX (64*1024+3)
|
||||||
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);
|
|
||||||
|
|
||||||
void IO_RegisterReadBHandler(Bitu port,IO_ReadBHandler * handler);
|
#define IO_MB 0x1
|
||||||
void IO_RegisterReadWHandler(Bitu port,IO_ReadWHandler * handler);
|
#define IO_MW 0x2
|
||||||
void IO_RegisterReadDHandler(Bitu port,IO_ReadDHandler * handler);
|
#define IO_MD 0x4
|
||||||
|
#define IO_MA (IO_MB | IO_MW | IO_MD )
|
||||||
|
|
||||||
void IO_RegisterWriteBHandler(Bitu port,IO_WriteBHandler * handler);
|
typedef Bitu IO_ReadHandler(Bitu port,Bitu iolen);
|
||||||
void IO_RegisterWriteWHandler(Bitu port,IO_WriteWHandler * handler);
|
typedef void IO_WriteHandler(Bitu port,Bitu val,Bitu iolen);
|
||||||
void IO_RegisterWriteDHandler(Bitu port,IO_WriteDHandler * handler);
|
|
||||||
|
|
||||||
void IO_FreeReadHandler(Bitu port);
|
extern IO_WriteHandler * io_writehandlers[3][IO_MAX];
|
||||||
void IO_FreeWriteHandler(Bitu port);
|
extern IO_ReadHandler * io_readhandlers[3][IO_MAX];
|
||||||
|
|
||||||
void IO_WriteB(Bitu port,Bit8u val);
|
void IO_RegisterReadHandler(Bitu port,IO_ReadHandler * handler,Bitu mask,Bitu range=1);
|
||||||
Bit8u IO_ReadB(Bitu port);
|
void IO_RegisterWriteHandler(Bitu port,IO_WriteHandler * handler,Bitu mask,Bitu range=1);
|
||||||
void IO_WriteW(Bitu port,Bit16u val);
|
|
||||||
Bit16u IO_ReadW(Bitu port);
|
void IO_FreeReadHandler(Bitu port,Bitu mask,Bitu range=0);
|
||||||
void IO_WriteD(Bitu port,Bit32u val);
|
void IO_FreeWriteHandler(Bitu port,Bitu mask,Bitu range=0);
|
||||||
Bit32u IO_ReadD(Bitu port);
|
|
||||||
|
INLINE void IO_WriteB(Bitu port,Bitu val) {
|
||||||
|
io_writehandlers[0][port](port,val,1);
|
||||||
|
};
|
||||||
|
INLINE void IO_WriteW(Bitu port,Bitu val) {
|
||||||
|
io_writehandlers[1][port](port,val,2);
|
||||||
|
};
|
||||||
|
INLINE void IO_WriteD(Bitu port,Bitu val) {
|
||||||
|
io_writehandlers[2][port](port,val,4);
|
||||||
|
};
|
||||||
|
|
||||||
|
INLINE Bitu IO_ReadB(Bitu port) {
|
||||||
|
return io_readhandlers[0][port](port,1);
|
||||||
|
}
|
||||||
|
INLINE Bitu IO_ReadW(Bitu port) {
|
||||||
|
return io_readhandlers[1][port](port,2);
|
||||||
|
}
|
||||||
|
INLINE Bitu IO_ReadD(Bitu port) {
|
||||||
|
return io_readhandlers[2][port](port,4);
|
||||||
|
}
|
||||||
|
|
||||||
INLINE void IO_Write(Bitu port,Bit8u val) {
|
INLINE void IO_Write(Bitu port,Bit8u val) {
|
||||||
IO_WriteB(port,val);
|
IO_WriteB(port,val);
|
||||||
@ -48,11 +62,4 @@ INLINE Bit8u IO_Read(Bitu port){
|
|||||||
return IO_ReadB(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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
92
include/ipx.h
Normal file
92
include/ipx.h
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/*
|
||||||
|
* 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _IPX_H_
|
||||||
|
#define _IPX_H_
|
||||||
|
|
||||||
|
// In Use Flag codes
|
||||||
|
#define USEFLAG_AVAILABLE 0x00
|
||||||
|
#define USEFLAG_AESTEMP 0xe0
|
||||||
|
#define USEFLAG_IPXCRIT 0xf8
|
||||||
|
#define USEFLAG_SPXLISTEN 0xf9
|
||||||
|
#define USEFLAG_PROCESSING 0xfa
|
||||||
|
#define USEFLAG_HOLDING 0xfb
|
||||||
|
#define USEFLAG_AESWAITING 0xfc
|
||||||
|
#define USEFLAG_AESCOUNT 0xfd
|
||||||
|
#define USEFLAG_LISTENING 0xfe
|
||||||
|
#define USEFLAG_SENDING 0xff
|
||||||
|
|
||||||
|
|
||||||
|
// Completion codes
|
||||||
|
#define COMP_SUCCESS 0x00
|
||||||
|
#define COMP_REMOTETERM 0xec
|
||||||
|
#define COMP_DISCONNECT 0xed
|
||||||
|
#define COMP_INVALIDID 0xee
|
||||||
|
#define COMP_SPXTABLEFULL 0xef
|
||||||
|
#define COMP_EVENTNOTCANCELED 0xf9
|
||||||
|
#define COMP_NOCONNECTION 0xfa
|
||||||
|
#define COMP_CANCELLED 0xfc
|
||||||
|
#define COMP_MALFORMED 0xfd
|
||||||
|
#define COMP_UNDELIVERABLE 0xfe
|
||||||
|
#define COMP_HARDWAREERROR 0xff
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma pack(1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// For Uint8 type
|
||||||
|
#include "SDL_net.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct PackedIP {
|
||||||
|
Uint32 host;
|
||||||
|
Uint16 port;
|
||||||
|
} GCC_ATTRIBUTE(packed);
|
||||||
|
|
||||||
|
struct nodeType {
|
||||||
|
Uint8 node[6];
|
||||||
|
}GCC_ATTRIBUTE(packed) ;
|
||||||
|
|
||||||
|
struct IPXHeader {
|
||||||
|
Uint8 checkSum[2];
|
||||||
|
Uint8 length[2];
|
||||||
|
Uint8 transControl; // Transport control
|
||||||
|
Uint8 pType; // Packet type
|
||||||
|
|
||||||
|
struct transport {
|
||||||
|
Uint8 network[4];
|
||||||
|
union addrtype {
|
||||||
|
nodeType byNode;
|
||||||
|
PackedIP byIP ;
|
||||||
|
} GCC_ATTRIBUTE(packed) addr;
|
||||||
|
Uint8 socket[2];
|
||||||
|
} dest, src;
|
||||||
|
} GCC_ATTRIBUTE(packed);
|
||||||
|
|
||||||
|
// The following routines may not be needed on all systems. On my build of SDL the IPaddress structure is 8 octects
|
||||||
|
// and therefore screws up my IPXheader structure since it needs to be packed.
|
||||||
|
|
||||||
|
void UnpackIP(PackedIP ipPack, IPaddress * ipAddr);
|
||||||
|
void PackIP(IPaddress ipAddr, PackedIP *ipPack);
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma pack()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
50
include/ipxserver.h
Normal file
50
include/ipxserver.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/*
|
||||||
|
* 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _IPXSERVER_H_
|
||||||
|
#define _IPXSERVER_H_
|
||||||
|
|
||||||
|
#if C_IPX
|
||||||
|
|
||||||
|
#include "SDL_net.h"
|
||||||
|
|
||||||
|
struct packetBuffer {
|
||||||
|
Bit8u buffer[1024];
|
||||||
|
Bit16s packetSize; // Packet size remaining in read
|
||||||
|
Bit16s packetRead; // Bytes read of total packet
|
||||||
|
bool inPacket; // In packet reception flag
|
||||||
|
bool connected; // Connected flag
|
||||||
|
bool waitsize;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define SOCKETTABLESIZE 16
|
||||||
|
#define IPXBUFFERSIZE 1024
|
||||||
|
#define CONVIP(hostvar) hostvar & 0xff, (hostvar >> 8) & 0xff, (hostvar >> 16) & 0xff, (hostvar >> 24) & 0xff
|
||||||
|
#define CONVIPX(hostvar) hostvar[0], hostvar[1], hostvar[2], hostvar[3], hostvar[4], hostvar[5]
|
||||||
|
|
||||||
|
|
||||||
|
void IPX_StopServer();
|
||||||
|
bool IPX_StartServer(Bit16u portnum);
|
||||||
|
bool IPX_isConnectedToServer(Bits tableNum, IPaddress ** ptrAddr);
|
||||||
|
|
||||||
|
Bit8u packetCRC(Bit8u *buffer, Bit16u bufSize);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
@ -20,6 +20,7 @@
|
|||||||
#define _KEYBOARD_H_
|
#define _KEYBOARD_H_
|
||||||
|
|
||||||
enum KBD_KEYS {
|
enum KBD_KEYS {
|
||||||
|
KBD_NONE,
|
||||||
KBD_1, KBD_2, KBD_3, KBD_4, KBD_5, KBD_6, KBD_7, KBD_8, KBD_9, KBD_0,
|
KBD_1, KBD_2, KBD_3, KBD_4, KBD_5, KBD_6, KBD_7, KBD_8, KBD_9, KBD_0,
|
||||||
KBD_q, KBD_w, KBD_e, KBD_r, KBD_t, KBD_y, KBD_u, KBD_i, KBD_o, KBD_p,
|
KBD_q, KBD_w, KBD_e, KBD_r, KBD_t, KBD_y, KBD_u, KBD_i, KBD_o, KBD_p,
|
||||||
KBD_a, KBD_s, KBD_d, KBD_f, KBD_g, KBD_h, KBD_j, KBD_k, KBD_l, KBD_z,
|
KBD_a, KBD_s, KBD_d, KBD_f, KBD_g, KBD_h, KBD_j, KBD_k, KBD_l, KBD_z,
|
||||||
@ -35,25 +36,17 @@ enum KBD_KEYS {
|
|||||||
KBD_grave,KBD_minus,KBD_equals,KBD_backslash,KBD_leftbracket,KBD_rightbracket,
|
KBD_grave,KBD_minus,KBD_equals,KBD_backslash,KBD_leftbracket,KBD_rightbracket,
|
||||||
KBD_semicolon,KBD_quote,KBD_period,KBD_comma,KBD_slash,
|
KBD_semicolon,KBD_quote,KBD_period,KBD_comma,KBD_slash,
|
||||||
|
|
||||||
|
KBD_printscreen,KBD_pause,
|
||||||
KBD_insert,KBD_home,KBD_pageup,KBD_delete,KBD_end,KBD_pagedown,
|
KBD_insert,KBD_home,KBD_pageup,KBD_delete,KBD_end,KBD_pagedown,
|
||||||
KBD_left,KBD_up,KBD_down,KBD_right,
|
KBD_left,KBD_up,KBD_down,KBD_right,
|
||||||
|
|
||||||
KBD_kp1,KBD_kp2,KBD_kp3,KBD_kp4,KBD_kp5,KBD_kp6,KBD_kp7,KBD_kp8,KBD_kp9,KBD_kp0,
|
KBD_kp1,KBD_kp2,KBD_kp3,KBD_kp4,KBD_kp5,KBD_kp6,KBD_kp7,KBD_kp8,KBD_kp9,KBD_kp0,
|
||||||
KBD_kpslash,KBD_kpmultiply,KBD_kpminus,KBD_kpplus,KBD_kpenter,KBD_kpperiod,
|
KBD_kpdivide,KBD_kpmultiply,KBD_kpminus,KBD_kpplus,KBD_kpenter,KBD_kpperiod,
|
||||||
|
|
||||||
|
|
||||||
KBD_LAST
|
KBD_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void(KEYBOARD_EventHandler)(void);
|
void KEYBOARD_AddKey(KBD_KEYS keytype,bool pressed);
|
||||||
|
|
||||||
void KEYBOARD_AddEvent(Bitu keytype,Bitu state,KEYBOARD_EventHandler * handler);
|
|
||||||
void KEYBOARD_AddKey(KBD_KEYS key,Bitu ascii,Bitu mod,bool pressed);
|
|
||||||
void KEYBOARD_ReadKey(Bitu & scancode,Bitu & ascii,Bitu & mod);
|
|
||||||
|
|
||||||
|
|
||||||
#define KBD_MOD_ALT 0x1
|
|
||||||
#define KBD_MOD_CTRL 0x2
|
|
||||||
#define KBD_MOD_SHIFT 0x4
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
40
include/mapper.h
Normal file
40
include/mapper.h
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MAPPER_H_
|
||||||
|
#define MAPPER_H_
|
||||||
|
|
||||||
|
enum MapKeys {
|
||||||
|
MK_f1,MK_f2,MK_f3,MK_f4,MK_f5,MK_f6,MK_f7,MK_f8,MK_f9,MK_f10,MK_f11,MK_f12,
|
||||||
|
MK_return,MK_kpminus,MK_scrolllock,MK_printscreen,MK_pause,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void (MAPPER_Handler)(void);
|
||||||
|
void MAPPER_AddHandler(MAPPER_Handler * handler,MapKeys key,Bitu mods,char * eventname,char * buttonname);
|
||||||
|
void MAPPER_Init(void);
|
||||||
|
void MAPPER_StartUp(Section * sec);
|
||||||
|
void MAPPER_Run(void);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define MMOD1 0x1
|
||||||
|
#define MMOD2 0x2
|
||||||
|
|
||||||
|
#endif
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
@ -20,8 +20,6 @@
|
|||||||
#define __MEM_H
|
#define __MEM_H
|
||||||
#include <dosbox.h>
|
#include <dosbox.h>
|
||||||
|
|
||||||
#define bmemcpy(mem1,mem2,size) memcpy((void *)mem1,(void *)mem2,size)
|
|
||||||
|
|
||||||
typedef Bit32u PhysPt;
|
typedef Bit32u PhysPt;
|
||||||
typedef Bit8u * HostPt;
|
typedef Bit8u * HostPt;
|
||||||
typedef Bit32u RealPt;
|
typedef Bit32u RealPt;
|
||||||
@ -30,6 +28,8 @@ typedef Bit32s MemHandle;
|
|||||||
|
|
||||||
#define MEM_PAGESIZE 4096
|
#define MEM_PAGESIZE 4096
|
||||||
|
|
||||||
|
extern HostPt MemBase;
|
||||||
|
|
||||||
bool MEM_A20_Enabled(void);
|
bool MEM_A20_Enabled(void);
|
||||||
void MEM_A20_Enable(bool enable);
|
void MEM_A20_Enable(bool enable);
|
||||||
|
|
||||||
@ -123,9 +123,25 @@ void mem_writeb(PhysPt pt,Bit8u val);
|
|||||||
void mem_writew(PhysPt pt,Bit16u val);
|
void mem_writew(PhysPt pt,Bit16u val);
|
||||||
void mem_writed(PhysPt pt,Bit32u val);
|
void mem_writed(PhysPt pt,Bit32u val);
|
||||||
|
|
||||||
void phys_writeb(PhysPt addr,Bit8u val);
|
INLINE void phys_writeb(PhysPt addr,Bit8u val) {
|
||||||
void phys_writew(PhysPt addr,Bit16u val);
|
host_writeb(MemBase+addr,val);
|
||||||
void phys_writed(PhysPt addr,Bit32u val);
|
}
|
||||||
|
INLINE void phys_writew(PhysPt addr,Bit16u val){
|
||||||
|
host_writew(MemBase+addr,val);
|
||||||
|
}
|
||||||
|
INLINE void phys_writed(PhysPt addr,Bit32u val){
|
||||||
|
host_writed(MemBase+addr,val);
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE Bit8u phys_readb(PhysPt addr) {
|
||||||
|
return host_readb(MemBase+addr);
|
||||||
|
}
|
||||||
|
INLINE Bit16u phys_readw(PhysPt addr){
|
||||||
|
return host_readw(MemBase+addr);
|
||||||
|
}
|
||||||
|
INLINE Bit32u phys_readd(PhysPt addr){
|
||||||
|
return host_readd(MemBase+addr);
|
||||||
|
}
|
||||||
|
|
||||||
/* These don't check for alignment, better be sure it's correct */
|
/* These don't check for alignment, better be sure it's correct */
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
@ -17,25 +17,54 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
typedef void (*MIXER_MixHandler)(Bit8u * sampdate,Bit32u len);
|
typedef void (*MIXER_MixHandler)(Bit8u * sampdate,Bit32u len);
|
||||||
|
typedef void (*MIXER_Handler)(Bitu len);
|
||||||
|
|
||||||
#define MIXER_8MONO 0
|
enum BlahModes {
|
||||||
#define MIXER_8STEREO 1
|
MIXER_8MONO,MIXER_8STEREO,
|
||||||
#define MIXER_16MONO 2
|
MIXER_16MONO,MIXER_16STEREO
|
||||||
#define MIXER_16STEREO 3
|
};
|
||||||
|
|
||||||
|
enum MixerModes {
|
||||||
|
M_8M,M_8S,
|
||||||
|
M_16M,M_16S,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MIXER_BUFSIZE (16*1024)
|
||||||
|
#define MIXER_BUFMASK (MIXER_BUFSIZE-1)
|
||||||
|
extern Bit8u MixTemp[MIXER_BUFSIZE];
|
||||||
|
|
||||||
#define MAX_AUDIO ((1<<(16-1))-1)
|
#define MAX_AUDIO ((1<<(16-1))-1)
|
||||||
#define MIN_AUDIO -(1<<(16-1))
|
#define MIN_AUDIO -(1<<(16-1))
|
||||||
|
|
||||||
|
class MixerChannel {
|
||||||
|
public:
|
||||||
|
void SetVolume(float _left,float _right);
|
||||||
|
void UpdateVolume(void);
|
||||||
|
void SetFreq(Bitu _freq);
|
||||||
|
void Mix(Bitu _needed);
|
||||||
|
void AddSilence(void); //Fill up until needed
|
||||||
|
template<bool _8bit,bool stereo>
|
||||||
|
void AddSamples(Bitu len,void * data);
|
||||||
|
void AddSamples_m8(Bitu len,Bit8u * data);
|
||||||
|
void AddSamples_s8(Bitu len,Bit8u * data);
|
||||||
|
void AddSamples_m16(Bitu len,Bit16s * data);
|
||||||
|
void AddSamples_s16(Bitu len,Bit16s * data);
|
||||||
|
void AddStretched(Bitu len,Bit16s * data); //Strech block up into needed data
|
||||||
|
void FillUp(void);
|
||||||
|
void Enable(bool _yesno);
|
||||||
|
MIXER_Handler handler;
|
||||||
|
float volmain[2];
|
||||||
|
Bit32s volmul[2];
|
||||||
|
Bitu freq_add,freq_index;
|
||||||
|
Bitu done,needed;
|
||||||
|
Bits last[2];
|
||||||
|
char * name;
|
||||||
|
bool enabled;
|
||||||
|
MixerChannel * next;
|
||||||
|
};
|
||||||
|
|
||||||
|
MixerChannel * MIXER_AddChannel(MIXER_Handler handler,Bitu freq,char * name);
|
||||||
struct MIXER_Channel;
|
MixerChannel * MIXER_FindChannel(const char * name);
|
||||||
|
|
||||||
|
|
||||||
MIXER_Channel * MIXER_AddChannel(MIXER_MixHandler handler,Bit32u freq,char * name);
|
|
||||||
void MIXER_SetVolume(MIXER_Channel * chan,Bit8u vol);
|
|
||||||
void MIXER_SetFreq(MIXER_Channel * chan,Bit32u freq);
|
|
||||||
void MIXER_SetMode(MIXER_Channel * chan,Bit8u mode);
|
|
||||||
void MIXER_Enable(MIXER_Channel * chan,bool enable);
|
|
||||||
|
|
||||||
/* PC Speakers functions, tightly related to the timer functions */
|
/* PC Speakers functions, tightly related to the timer functions */
|
||||||
|
|
||||||
|
@ -9,16 +9,23 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* $Id: mouse.h,v 1.7 2004/08/04 09:12:51 qbix79 Exp $ */
|
||||||
|
|
||||||
|
#ifndef _MOUSE_H_
|
||||||
|
#define _MOUSE_H_
|
||||||
|
|
||||||
void Mouse_ShowCursor(void);
|
void Mouse_ShowCursor(void);
|
||||||
void Mouse_HideCursor(void);
|
void Mouse_HideCursor(void);
|
||||||
|
|
||||||
|
void Mouse_SetPS2State(bool use);
|
||||||
|
void Mouse_ChangePS2Callback(Bit16u pseg, Bit16u pofs);
|
||||||
|
|
||||||
void Mouse_CursorMoved(float x,float y);
|
void Mouse_CursorMoved(float x,float y);
|
||||||
void Mouse_CursorSet(float x,float y);
|
void Mouse_CursorSet(float x,float y);
|
||||||
@ -28,3 +35,5 @@ void Mouse_ButtonReleased(Bit8u button);
|
|||||||
void Mouse_AutoLock(bool enable);
|
void Mouse_AutoLock(bool enable);
|
||||||
void Mouse_NewVideoMode(void);
|
void Mouse_NewVideoMode(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@ -9,16 +9,19 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* $Id: paging.h,v 1.11 2004/09/07 18:21:51 qbix79 Exp $ */
|
||||||
|
|
||||||
#ifndef _PAGING_H_
|
#ifndef _PAGING_H_
|
||||||
#define _PAGING_H_
|
#define _PAGING_H_
|
||||||
|
|
||||||
|
#include "dosbox.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
|
|
||||||
class PageDirectory;
|
class PageDirectory;
|
||||||
@ -70,13 +73,10 @@ bool PAGING_MakePhysPage(Bitu & page);
|
|||||||
void MEM_SetLFB(Bitu _page,Bitu _pages,HostPt _pt);
|
void MEM_SetLFB(Bitu _page,Bitu _pages,HostPt _pt);
|
||||||
void MEM_SetPageHandler(Bitu phys_page,Bitu pages,PageHandler * handler);
|
void MEM_SetPageHandler(Bitu phys_page,Bitu pages,PageHandler * handler);
|
||||||
|
|
||||||
Bit32u MEM_PhysReadD(Bitu addr);
|
#ifdef _MSC_VER
|
||||||
|
#pragma pack (1)
|
||||||
|
#endif
|
||||||
|
struct X86_PageEntryBlock{
|
||||||
|
|
||||||
#pragma pack(1)
|
|
||||||
typedef struct {
|
|
||||||
Bit32u p:1;
|
Bit32u p:1;
|
||||||
Bit32u wr:1;
|
Bit32u wr:1;
|
||||||
Bit32u us:1;
|
Bit32u us:1;
|
||||||
@ -88,8 +88,11 @@ typedef struct {
|
|||||||
Bit32u g:1;
|
Bit32u g:1;
|
||||||
Bit32u avl:3;
|
Bit32u avl:3;
|
||||||
Bit32u base:20;
|
Bit32u base:20;
|
||||||
} X86_PageEntryBlock GCC_ATTRIBUTE(packed);
|
} GCC_ATTRIBUTE(packed);
|
||||||
#pragma pack()
|
#ifdef _MSC_VER
|
||||||
|
#pragma pack ()
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
union X86PageEntry {
|
union X86PageEntry {
|
||||||
Bit32u load;
|
Bit32u load;
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
@ -26,41 +26,36 @@ extern Bits CPU_CycleLeft;
|
|||||||
extern Bits CPU_CycleMax;
|
extern Bits CPU_CycleMax;
|
||||||
|
|
||||||
typedef void (PIC_EOIHandler) (void);
|
typedef void (PIC_EOIHandler) (void);
|
||||||
typedef void (* PIC_EventHandler)(void);
|
typedef void (* PIC_EventHandler)(Bitu val);
|
||||||
|
|
||||||
|
|
||||||
#define PIC_MAXIRQ 15
|
#define PIC_MAXIRQ 15
|
||||||
#define PIC_NOIRQ 0xFF
|
#define PIC_NOIRQ 0xFF
|
||||||
|
|
||||||
|
|
||||||
extern Bitu PIC_IRQCheck;
|
extern Bitu PIC_IRQCheck;
|
||||||
extern Bitu PIC_IRQActive;
|
extern Bitu PIC_IRQActive;
|
||||||
extern Bitu PIC_Ticks;
|
extern Bitu PIC_Ticks;
|
||||||
|
|
||||||
INLINE Bitu PIC_Index(void) {
|
INLINE float PIC_TickIndex(void) {
|
||||||
return ((CPU_CycleMax-CPU_CycleLeft-CPU_Cycles)*1000)/CPU_CycleMax;
|
return (CPU_CycleMax-CPU_CycleLeft-CPU_Cycles)/(float)CPU_CycleMax;
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE Bits PIC_MakeCycles(Bitu amount) {
|
INLINE Bits PIC_MakeCycles(double amount) {
|
||||||
return (CPU_CycleMax*amount)/1000;
|
return (Bits)(CPU_CycleMax*amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
INLINE Bit64u PIC_MicroCount(void) {
|
INLINE double PIC_FullIndex(void) {
|
||||||
return PIC_Ticks*1000+PIC_Index();
|
return PIC_Ticks+PIC_TickIndex();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PIC_ActivateIRQ(Bitu irq);
|
void PIC_ActivateIRQ(Bitu irq);
|
||||||
|
|
||||||
void PIC_DeActivateIRQ(Bitu irq);
|
void PIC_DeActivateIRQ(Bitu irq);
|
||||||
|
|
||||||
void PIC_runIRQs(void);
|
void PIC_runIRQs(void);
|
||||||
|
|
||||||
void PIC_RegisterIRQ(Bitu irq,PIC_EOIHandler handler,char * name);
|
|
||||||
void PIC_FreeIRQ(Bitu irq);
|
|
||||||
bool PIC_RunQueue(void);
|
bool PIC_RunQueue(void);
|
||||||
|
|
||||||
void PIC_AddEvent(PIC_EventHandler handler,Bitu delay);
|
//Delay in milliseconds
|
||||||
|
void PIC_AddEvent(PIC_EventHandler handler,float delay,Bitu val=0);
|
||||||
void PIC_RemoveEvents(PIC_EventHandler handler);
|
void PIC_RemoveEvents(PIC_EventHandler handler);
|
||||||
|
|
||||||
void PIC_SetIRQMask(Bitu irq, bool masked);
|
void PIC_SetIRQMask(Bitu irq, bool masked);
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
@ -19,21 +19,13 @@
|
|||||||
#ifndef __RENDER_H
|
#ifndef __RENDER_H
|
||||||
#define __RENDER_H
|
#define __RENDER_H
|
||||||
|
|
||||||
enum RENDER_Operation {
|
typedef void (* RENDER_Line_Handler)(const Bit8u * src);
|
||||||
OP_None,
|
|
||||||
OP_Shot,
|
|
||||||
OP_Normal2x,
|
|
||||||
OP_AdvMame2x,
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef void (* RENDER_Line_Handler)(Bit8u * src);
|
void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,double ratio,bool dblw,bool dblh);
|
||||||
|
|
||||||
void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,double ratio,Bitu scalew,Bitu scaleh);
|
|
||||||
bool RENDER_StartUpdate(void);
|
bool RENDER_StartUpdate(void);
|
||||||
void RENDER_EndUpdate(void);
|
void RENDER_EndUpdate(void);
|
||||||
void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue);
|
void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue);
|
||||||
extern RENDER_Line_Handler RENDER_DrawLine;
|
extern RENDER_Line_Handler RENDER_DrawLine;
|
||||||
extern Bit8u * RENDER_TempLine;
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
@ -19,118 +19,137 @@
|
|||||||
#if !defined __SERIALPORT_H
|
#if !defined __SERIALPORT_H
|
||||||
#define __SERIALPORT_H
|
#define __SERIALPORT_H
|
||||||
|
|
||||||
#include <dosbox.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "dosbox.h"
|
||||||
|
|
||||||
//If it's too high you overflow terminal clients buffers i think
|
//If it's too high you overflow terminal clients buffers i think
|
||||||
#define FIFO_SIZE (1024)
|
#define QUEUE_SIZE 1024
|
||||||
|
|
||||||
// Serial port interface //
|
// Serial port interface //
|
||||||
|
|
||||||
#define M_CTS 0x01
|
#define MS_CTS 0x01
|
||||||
#define M_DSR 0x02
|
#define MS_DSR 0x02
|
||||||
#define M_RI 0x04
|
#define MS_RI 0x04
|
||||||
#define M_DCD 0x08
|
#define MS_DCD 0x08
|
||||||
|
|
||||||
enum INT_TYPES {
|
#define MC_DTR 0x1
|
||||||
INT_MS,
|
#define MC_RTS 0x2
|
||||||
INT_TX,
|
|
||||||
INT_RX,
|
|
||||||
INT_RX_FIFO,
|
class CFifo {
|
||||||
INT_LS,
|
public:
|
||||||
INT_NONE,
|
CFifo(Bitu _size) {
|
||||||
|
size=_size;
|
||||||
|
pos=used=0;
|
||||||
|
data=new Bit8u[size];
|
||||||
|
}
|
||||||
|
~CFifo() {
|
||||||
|
delete[] data;
|
||||||
|
}
|
||||||
|
INLINE Bitu left(void) {
|
||||||
|
return size-used;
|
||||||
|
}
|
||||||
|
INLINE Bitu inuse(void) {
|
||||||
|
return used;
|
||||||
|
}
|
||||||
|
void clear(void) {
|
||||||
|
used=pos=0;
|
||||||
|
}
|
||||||
|
bool isFull() {
|
||||||
|
return (used >= size);
|
||||||
|
}
|
||||||
|
void addb(Bit8u _val) {
|
||||||
|
assert(used<size);
|
||||||
|
Bitu where=pos+used;
|
||||||
|
if (where>=size) where-=size;
|
||||||
|
data[where]=_val;
|
||||||
|
used++;
|
||||||
|
}
|
||||||
|
void adds(Bit8u * _str,Bitu _len) {
|
||||||
|
assert((used+_len)<=size);
|
||||||
|
Bitu where=pos+used;
|
||||||
|
used+=_len;
|
||||||
|
while (_len--) {
|
||||||
|
if (where>=size) where-=size;
|
||||||
|
data[where++]=*_str++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Bit8u getb(void) {
|
||||||
|
if (!used) return data[pos];
|
||||||
|
Bitu where=pos;
|
||||||
|
if (++pos>=size) pos-=size;
|
||||||
|
used--;
|
||||||
|
return data[where];
|
||||||
|
}
|
||||||
|
void gets(Bit8u * _str,Bitu _len) {
|
||||||
|
assert(used>=_len);
|
||||||
|
used-=_len;
|
||||||
|
while (_len--) {
|
||||||
|
*_str++=data[pos];
|
||||||
|
if (++pos>=size) pos-=size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Bit8u * data;
|
||||||
|
Bitu size,pos,used;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void MControl_Handler(Bitu mc);
|
|
||||||
|
|
||||||
class CSerial {
|
class CSerial {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
CSerial() {
|
||||||
|
|
||||||
|
}
|
||||||
// Constructor takes base port (0x3f0, 0x2f0, 0x2e0, etc.), IRQ, and initial bps //
|
// Constructor takes base port (0x3f0, 0x2f0, 0x2e0, etc.), IRQ, and initial bps //
|
||||||
CSerial (Bit16u initbase, Bit8u initirq, Bit32u initbps);
|
CSerial (Bit16u initbase, Bit8u initirq, Bit32u initbps);
|
||||||
virtual ~CSerial();
|
virtual ~CSerial();
|
||||||
|
|
||||||
// External port functions for IOHandlers //
|
void write_reg(Bitu reg, Bitu val);
|
||||||
void write_port(Bit32u port, Bit8u val);
|
Bitu read_reg(Bitu reg);
|
||||||
Bit8u read_port(Bit32u port);
|
|
||||||
|
|
||||||
static void write_serial(Bit32u port,Bit8u val);
|
void SetModemStatus(Bit8u status);
|
||||||
static Bit8u read_serial(Bit32u port);
|
virtual bool CanRecv(void)=0;
|
||||||
|
virtual bool CanSend(void)=0;
|
||||||
void SetMCHandler(MControl_Handler * mcontrol);
|
virtual void Send(Bit8u val)=0;
|
||||||
|
virtual Bit8u Recv(Bit8u val)=0;
|
||||||
/* Allow the modem to change the modem status bits */
|
virtual void Timer(void);
|
||||||
void setmodemstatus(Bit8u status);
|
|
||||||
Bit8u getmodemstatus(void);
|
|
||||||
Bit8u getlinestatus(void);
|
|
||||||
|
|
||||||
void checkint(void);
|
void checkint(void);
|
||||||
void raiseint(INT_TYPES type);
|
|
||||||
void lowerint(INT_TYPES type);
|
|
||||||
|
|
||||||
/* Access to the receive fifo */
|
Bitu base;
|
||||||
Bitu rx_free();
|
Bitu irq;
|
||||||
void rx_addb(Bit8u byte);
|
Bitu bps;
|
||||||
void rx_adds(Bit8u * data,Bitu size);
|
Bit8u mctrl;
|
||||||
Bitu rx_size();
|
|
||||||
Bit8u rx_readb(void);
|
|
||||||
|
|
||||||
/* Access to the transmit fifo */
|
CFifo *rqueue;
|
||||||
Bitu tx_free();
|
CFifo *tqueue;
|
||||||
void tx_addb(Bit8u byte);
|
|
||||||
Bitu tx_size();
|
|
||||||
Bit8u tx_readb(void);
|
|
||||||
|
|
||||||
|
|
||||||
// These variables maintain the status of the serial port
|
|
||||||
Bit16u base;
|
|
||||||
Bit16u irq;
|
|
||||||
Bit32u bps;
|
|
||||||
|
|
||||||
bool FIFOenabled;
|
|
||||||
Bit16u FIFOsize;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void UpdateBaudrate(void);
|
||||||
void setdivisor(Bit8u dmsb, Bit8u dlsb);
|
bool FIFOenabled;
|
||||||
void checkforirq(void);
|
Bit8u FIFOsize;
|
||||||
struct {
|
bool dotxint;
|
||||||
Bitu used;
|
|
||||||
Bitu pos;
|
|
||||||
Bit8u data[FIFO_SIZE];
|
|
||||||
} rx_fifo,tx_fifo;
|
|
||||||
struct {
|
|
||||||
Bitu requested;
|
|
||||||
Bitu enabled;
|
|
||||||
INT_TYPES active;
|
|
||||||
} ints;
|
|
||||||
|
|
||||||
Bitu rx_lastread;
|
|
||||||
Bit8u irq_pending;
|
|
||||||
|
|
||||||
Bit8u scratch;
|
Bit8u scratch;
|
||||||
Bit8u dlab;
|
Bit8u dlab;
|
||||||
Bit8u divisor_lsb;
|
Bit8u divisor_lsb;
|
||||||
Bit8u divisor_msb;
|
Bit8u divisor_msb;
|
||||||
Bit8u wordlen;
|
|
||||||
Bit8u dtr;
|
|
||||||
Bit8u rts;
|
|
||||||
Bit8u out1;
|
|
||||||
Bit8u out2;
|
|
||||||
Bit8u local_loopback;
|
Bit8u local_loopback;
|
||||||
Bit8u linectrl;
|
Bit8u iir;
|
||||||
Bit8u intid;
|
Bit8u ier;
|
||||||
Bit8u ierval;
|
|
||||||
Bit8u mstatus;
|
Bit8u mstatus;
|
||||||
|
|
||||||
Bit8u txval;
|
Bit8u linectrl;
|
||||||
Bit8u timeout;
|
Bit8u errors;
|
||||||
|
|
||||||
MControl_Handler * mc_handler;
|
|
||||||
char remotestr[4096];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// This function returns the CSerial objects for ports 1-4 //
|
#include <list>
|
||||||
CSerial *getComport(Bitu portnum);
|
|
||||||
|
typedef std::list<CSerial *> CSerialList;
|
||||||
|
typedef std::list<CSerial *>::iterator CSerial_it;
|
||||||
|
|
||||||
|
extern CSerialList seriallist;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -9,14 +9,14 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: setup.h,v 1.15 2004/01/29 09:26:43 qbix79 Exp $ */
|
/* $Id: setup.h,v 1.16 2004/08/04 09:12:51 qbix79 Exp $ */
|
||||||
|
|
||||||
#ifndef _SETUP_H_
|
#ifndef _SETUP_H_
|
||||||
#define _SETUP_H_
|
#define _SETUP_H_
|
||||||
|
@ -9,14 +9,14 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: shell.h,v 1.2 2004/01/10 14:03:33 qbix79 Exp $ */
|
/* $Id: shell.h,v 1.7 2004/09/09 18:36:50 qbix79 Exp $ */
|
||||||
|
|
||||||
#ifndef SHELL_H_
|
#ifndef SHELL_H_
|
||||||
#define SHELL_H_
|
#define SHELL_H_
|
||||||
@ -57,9 +57,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
class DOS_Shell : public Program {
|
class DOS_Shell : public Program {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::list<std::string> l_history, l_completion;
|
std::list<std::string> l_history, l_completion;
|
||||||
|
|
||||||
char *completion_start;
|
char *completion_start;
|
||||||
@ -102,6 +100,8 @@ public:
|
|||||||
void CMD_PAUSE(char * args);
|
void CMD_PAUSE(char * args);
|
||||||
void CMD_SUBST(char* args);
|
void CMD_SUBST(char* args);
|
||||||
void CMD_LOADHIGH(char* args);
|
void CMD_LOADHIGH(char* args);
|
||||||
|
void CMD_CHOICE(char * args);
|
||||||
|
void CMD_ATTRIB(char * args);
|
||||||
/* The shell's variables */
|
/* The shell's variables */
|
||||||
Bit16u input_handle;
|
Bit16u input_handle;
|
||||||
BatchFile * bf;
|
BatchFile * bf;
|
||||||
@ -117,15 +117,12 @@ struct SHELL_Cmd {
|
|||||||
const char * help; /* String with command help */
|
const char * help; /* String with command help */
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void StripSpaces(char*&args)
|
static inline void StripSpaces(char*&args) {
|
||||||
{
|
while(*args && ((*args == ' ') || (*args == '\t')))
|
||||||
while(*args && (*args == ' '))
|
|
||||||
args++;
|
args++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline char* ExpandDot(char*args, char* buffer) {
|
||||||
static inline char* ExpandDot(char*args, char* buffer)
|
|
||||||
{
|
|
||||||
if(*args=='.')
|
if(*args=='.')
|
||||||
{
|
{
|
||||||
if(*(args+1)==0)
|
if(*(args+1)==0)
|
||||||
@ -139,11 +136,11 @@ static inline char* ExpandDot(char*args, char* buffer)
|
|||||||
buffer[1]=0;
|
buffer[1]=0;
|
||||||
strcat(buffer,args);
|
strcat(buffer,args);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
} else
|
||||||
|
strcpy (buffer, args);
|
||||||
}
|
}
|
||||||
else strcpy(buffer,args);
|
else strcpy(buffer,args);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
@ -19,11 +19,11 @@
|
|||||||
#if !defined __SUPPORT_H
|
#if !defined __SUPPORT_H
|
||||||
#define __SUPPORT_H
|
#define __SUPPORT_H
|
||||||
|
|
||||||
|
|
||||||
#include <dosbox.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include "dosbox.h"
|
||||||
|
|
||||||
#if defined (_MSC_VER) /* MS Visual C++ */
|
#if defined (_MSC_VER) /* MS Visual C++ */
|
||||||
#define strcasecmp(a,b) stricmp(a,b)
|
#define strcasecmp(a,b) stricmp(a,b)
|
||||||
#define strncasecmp(a,b,n) _strnicmp(a,b,n)
|
#define strncasecmp(a,b,n) _strnicmp(a,b,n)
|
||||||
@ -39,13 +39,16 @@
|
|||||||
|
|
||||||
void strreplace(char * str,char o,char n);
|
void strreplace(char * str,char o,char n);
|
||||||
char *ltrim(char *str);
|
char *ltrim(char *str);
|
||||||
void rtrim(char * const str);
|
char *rtrim(char *str);
|
||||||
char *trim(char *str);
|
char *trim(char * str);
|
||||||
|
|
||||||
bool ScanCMDBool(char * cmd,char * check);
|
bool ScanCMDBool(char * cmd,char * check);
|
||||||
char * ScanCMDRemain(char * cmd);
|
char * ScanCMDRemain(char * cmd);
|
||||||
bool ScanCMDHex(char * cmd,char * check,Bits * result);
|
char * StripWord(char *&cmd);
|
||||||
char * StripWord(char * cmd);
|
bool IsDecWord(char * word);
|
||||||
|
bool IsHexWord(char * word);
|
||||||
|
Bits ConvDecWord(char * word);
|
||||||
|
Bits ConvHexWord(char * word);
|
||||||
|
|
||||||
INLINE char * upcase(char * str) {
|
INLINE char * upcase(char * str) {
|
||||||
for (char* idx = str; *idx ; idx++) *idx = toupper(*idx);
|
for (char* idx = str; *idx ; idx++) *idx = toupper(*idx);
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
@ -25,19 +25,11 @@
|
|||||||
|
|
||||||
#define GetTicks() SDL_GetTicks()
|
#define GetTicks() SDL_GetTicks()
|
||||||
|
|
||||||
typedef void (*TIMER_TickHandler)(Bitu ticks);
|
typedef void (*TIMER_TickHandler)(void);
|
||||||
typedef void (*TIMER_MicroHandler)(void);
|
|
||||||
|
|
||||||
typedef void TIMER_Block;
|
|
||||||
|
|
||||||
|
|
||||||
/* Register a function that gets called everytime if 1 or more ticks pass */
|
/* Register a function that gets called everytime if 1 or more ticks pass */
|
||||||
TIMER_Block * TIMER_RegisterTickHandler(TIMER_TickHandler handler);
|
void TIMER_AddTickHandler(TIMER_TickHandler handler);
|
||||||
/* Register a function to be called every x microseconds */
|
void TIMER_DelTickHandler(TIMER_TickHandler handler);
|
||||||
TIMER_Block * TIMER_RegisterMicroHandler(TIMER_MicroHandler handler,Bitu micro);
|
|
||||||
|
|
||||||
/* Set the microseconds value to a new value */
|
|
||||||
void TIMER_SetNewMicro(TIMER_Block * block,Bitu micro);
|
|
||||||
|
|
||||||
/* This will add 1 milliscond to all timers */
|
/* This will add 1 milliscond to all timers */
|
||||||
void TIMER_AddTick(void);
|
void TIMER_AddTick(void);
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
@ -23,13 +23,13 @@
|
|||||||
#include "dosbox.h"
|
#include "dosbox.h"
|
||||||
|
|
||||||
enum VGAModes {
|
enum VGAModes {
|
||||||
M_TEXT2,M_TEXT16,
|
M_CGA2,M_CGA4,
|
||||||
M_HERC,
|
M_EGA16,
|
||||||
M_CGA2,M_CGA4,M_CGA16,
|
|
||||||
M_TANDY16,
|
|
||||||
M_EGA2,M_EGA4,M_EGA16,
|
|
||||||
M_VGA,
|
M_VGA,
|
||||||
M_LIN8,
|
M_LIN8,
|
||||||
|
M_TEXT,
|
||||||
|
M_HERC_GFX,M_HERC_TEXT,
|
||||||
|
M_CGA16,M_TANDY2,M_TANDY4,M_TANDY16,M_TANDY_TEXT,
|
||||||
M_ERROR,
|
M_ERROR,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -60,9 +60,7 @@ typedef struct {
|
|||||||
|
|
||||||
/* Some other screen related variables */
|
/* Some other screen related variables */
|
||||||
Bitu line_compare;
|
Bitu line_compare;
|
||||||
|
|
||||||
bool chained; /* Enable or Disabled Chain 4 Mode */
|
bool chained; /* Enable or Disabled Chain 4 Mode */
|
||||||
bool blinking; /* Attribute bit 7 is blinking */
|
|
||||||
|
|
||||||
/* Pixel Scrolling */
|
/* Pixel Scrolling */
|
||||||
Bit8u pel_panning; /* Amount of pixels to skip when starting horizontal line */
|
Bit8u pel_panning; /* Amount of pixels to skip when starting horizontal line */
|
||||||
@ -91,10 +89,8 @@ typedef struct {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool resizing;
|
bool resizing;
|
||||||
bool drawing;
|
|
||||||
Bitu width;
|
Bitu width;
|
||||||
Bitu height;
|
Bitu height;
|
||||||
Bitu pitch;
|
|
||||||
Bitu blocks;
|
Bitu blocks;
|
||||||
Bitu panning;
|
Bitu panning;
|
||||||
Bitu address;
|
Bitu address;
|
||||||
@ -102,49 +98,62 @@ typedef struct {
|
|||||||
Bitu address_line_total;
|
Bitu address_line_total;
|
||||||
Bitu address_line;
|
Bitu address_line;
|
||||||
Bitu lines_total;
|
Bitu lines_total;
|
||||||
Bitu lines_left;
|
Bitu lines_done;
|
||||||
Bitu lines_scaled;
|
Bitu lines_scaled;
|
||||||
Bitu split_line;
|
Bitu split_line;
|
||||||
Bitu parts_total;
|
Bitu parts_total;
|
||||||
Bitu parts_lines;
|
Bitu parts_lines;
|
||||||
Bitu parts_left;
|
Bitu parts_left;
|
||||||
struct {
|
struct {
|
||||||
Bitu vtotal;
|
float vtotal;
|
||||||
Bitu vstart;
|
float vstart;
|
||||||
Bitu vend;
|
float vend;
|
||||||
Bitu htotal;
|
float htotal;
|
||||||
Bitu hstart;
|
float hstart;
|
||||||
Bitu hend;
|
float hend;
|
||||||
Bitu parts;
|
float parts;
|
||||||
} micro;
|
} delay;
|
||||||
Bitu scaleh;
|
|
||||||
bool double_scan;
|
bool double_scan;
|
||||||
bool double_scan_active;
|
bool doublewidth,doubleheight;
|
||||||
Bit8u font_height;
|
|
||||||
Bit8u font[64*1024];
|
Bit8u font[64*1024];
|
||||||
Bitu font1_start;
|
Bit8u * font_tables[2];
|
||||||
Bitu font2_start;
|
|
||||||
Bitu blinking;
|
Bitu blinking;
|
||||||
struct {
|
struct {
|
||||||
|
Bitu address;
|
||||||
Bit8u sline,eline;
|
Bit8u sline,eline;
|
||||||
Bit8u count,delay;
|
Bit8u count,delay;
|
||||||
Bit8u enabled;
|
Bit8u enabled;
|
||||||
} cursor;
|
} cursor;
|
||||||
} VGA_Draw;
|
} VGA_Draw;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Bit8u curmode;
|
||||||
|
Bit16u originx, originy;
|
||||||
|
Bit8u fstackpos, bstackpos;
|
||||||
|
Bit8u forestack[3];
|
||||||
|
Bit8u backstack[3];
|
||||||
|
Bit16u startaddr;
|
||||||
|
Bit8u posx, posy;
|
||||||
|
Bit8u mc[64][64];
|
||||||
|
} VGA_HWCURSOR;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Bit8u bank;
|
Bit8u bank;
|
||||||
Bit8u reg_lock1;
|
Bit8u reg_lock1;
|
||||||
Bit8u reg_lock2;
|
Bit8u reg_lock2;
|
||||||
Bit8u reg_31;
|
Bit8u reg_31;
|
||||||
Bit8u reg_35;
|
Bit8u reg_35;
|
||||||
|
Bit8u reg_40; // 8415/A functionality register
|
||||||
Bit8u reg_43;
|
Bit8u reg_43;
|
||||||
|
Bit8u reg_45; // Hardware graphics cursor
|
||||||
Bit8u reg_58;
|
Bit8u reg_58;
|
||||||
Bit8u reg_51;
|
Bit8u reg_51;
|
||||||
Bit8u reg_55;
|
Bit8u reg_55;
|
||||||
Bit8u ex_hor_overflow;
|
Bit8u ex_hor_overflow;
|
||||||
Bit8u ex_ver_overflow;
|
Bit8u ex_ver_overflow;
|
||||||
Bit16u la_window;
|
Bit16u la_window;
|
||||||
|
Bit8u misc_control_2;
|
||||||
|
Bit8u ext_mem_ctrl;
|
||||||
struct {
|
struct {
|
||||||
Bit8u r;
|
Bit8u r;
|
||||||
Bit8u n;
|
Bit8u n;
|
||||||
@ -154,6 +163,7 @@ typedef struct {
|
|||||||
Bit8u lock;
|
Bit8u lock;
|
||||||
Bit8u cmd;
|
Bit8u cmd;
|
||||||
} pll;
|
} pll;
|
||||||
|
VGA_HWCURSOR hgc;
|
||||||
} VGA_S3;
|
} VGA_S3;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -162,18 +172,28 @@ typedef struct {
|
|||||||
} VGA_HERC;
|
} VGA_HERC;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Bit8u mode_control;
|
Bit8u index;
|
||||||
Bit8u color_select;
|
Bit8u htotal;
|
||||||
} VGA_CGA;
|
Bit8u hdend;
|
||||||
|
Bit8u hsyncp;
|
||||||
|
Bit8u hsyncw;
|
||||||
|
Bit8u vtotal;
|
||||||
|
Bit8u vdend;
|
||||||
|
Bit8u vadjust;
|
||||||
|
Bit8u vsyncp;
|
||||||
|
Bit8u vsyncw;
|
||||||
|
Bit8u max_scanline;
|
||||||
|
} VGA_OTHER;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
Bit8u mode_control;
|
||||||
|
Bit8u color_select;
|
||||||
Bit8u mem_bank;
|
Bit8u mem_bank;
|
||||||
Bit8u disp_bank;
|
Bit8u disp_bank;
|
||||||
Bit8u reg_index;
|
Bit8u reg_index;
|
||||||
Bit8u mode_control1;
|
Bit8u gfx_control;
|
||||||
Bit8u palette_mask;
|
Bit8u palette_mask;
|
||||||
Bit8u border_color;
|
Bit8u border_color;
|
||||||
Bit8u mode_control2;
|
|
||||||
} VGA_TANDY;
|
} VGA_TANDY;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -256,7 +276,6 @@ typedef struct {
|
|||||||
Bit8u read_index;
|
Bit8u read_index;
|
||||||
Bitu first_changed;
|
Bitu first_changed;
|
||||||
RGBEntry rgb[0x100];
|
RGBEntry rgb[0x100];
|
||||||
Bit8u attr[16];
|
|
||||||
} VGA_Dac;
|
} VGA_Dac;
|
||||||
|
|
||||||
union VGA_Latch {
|
union VGA_Latch {
|
||||||
@ -285,8 +304,8 @@ typedef struct {
|
|||||||
VGA_Latch latch;
|
VGA_Latch latch;
|
||||||
VGA_S3 s3;
|
VGA_S3 s3;
|
||||||
VGA_HERC herc;
|
VGA_HERC herc;
|
||||||
VGA_CGA cga;
|
|
||||||
VGA_TANDY tandy;
|
VGA_TANDY tandy;
|
||||||
|
VGA_OTHER other;
|
||||||
VGA_Memory mem;
|
VGA_Memory mem;
|
||||||
} VGA_Type;
|
} VGA_Type;
|
||||||
|
|
||||||
@ -294,12 +313,15 @@ typedef struct {
|
|||||||
|
|
||||||
/* Functions for different resolutions */
|
/* Functions for different resolutions */
|
||||||
void VGA_SetMode(VGAModes mode);
|
void VGA_SetMode(VGAModes mode);
|
||||||
|
void VGA_DetermineMode(void);
|
||||||
void VGA_SetupHandlers(void);
|
void VGA_SetupHandlers(void);
|
||||||
void VGA_StartResize(void);
|
void VGA_StartResize(void);
|
||||||
void VGA_SetupDrawing(void);
|
void VGA_SetupDrawing(Bitu val);
|
||||||
|
void VGA_CheckScanLength(void);
|
||||||
|
|
||||||
/* Some DAC/Attribute functions */
|
/* Some DAC/Attribute functions */
|
||||||
void VGA_DAC_CombineColor(Bit8u attr,Bit8u pal);
|
void VGA_DAC_CombineColor(Bit8u attr,Bit8u pal);
|
||||||
|
void VGA_DAC_SetEntry(Bitu entry,Bit8u red,Bit8u green,Bit8u blue);
|
||||||
void VGA_ATTR_SetPalette(Bit8u index,Bit8u val);
|
void VGA_ATTR_SetPalette(Bit8u index,Bit8u val);
|
||||||
|
|
||||||
/* The VGA Subfunction startups */
|
/* The VGA Subfunction startups */
|
||||||
@ -310,6 +332,8 @@ void VGA_SetupCRTC(void);
|
|||||||
void VGA_SetupMisc(void);
|
void VGA_SetupMisc(void);
|
||||||
void VGA_SetupGFX(void);
|
void VGA_SetupGFX(void);
|
||||||
void VGA_SetupSEQ(void);
|
void VGA_SetupSEQ(void);
|
||||||
|
void VGA_SetupOther(void);
|
||||||
|
void VGA_SetupXGA(void);
|
||||||
|
|
||||||
/* Some Support Functions */
|
/* Some Support Functions */
|
||||||
void VGA_SetClock(Bitu which,Bitu target);
|
void VGA_SetClock(Bitu which,Bitu target);
|
||||||
@ -317,6 +341,8 @@ void VGA_DACSetEntirePalette(void);
|
|||||||
void VGA_StartRetrace(void);
|
void VGA_StartRetrace(void);
|
||||||
void VGA_StartUpdateLFB(void);
|
void VGA_StartUpdateLFB(void);
|
||||||
void VGA_SetBlinking(Bitu enabled);
|
void VGA_SetBlinking(Bitu enabled);
|
||||||
|
void VGA_SetCGA2Table(Bit8u val0,Bit8u val1);
|
||||||
|
void VGA_SetCGA4Table(Bit8u val0,Bit8u val1,Bit8u val2,Bit8u val3);
|
||||||
|
|
||||||
extern VGA_Type vga;
|
extern VGA_Type vga;
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
@ -28,21 +28,43 @@ struct GFX_PalEntry {
|
|||||||
Bit8u unused;
|
Bit8u unused;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define GFX_HASSCALING 0x0001
|
#define CAN_8 0x0001
|
||||||
#define GFX_HASCONVERT 0x0002
|
#define CAN_16 0x0002
|
||||||
|
#define CAN_32 0x0004
|
||||||
|
|
||||||
|
#define CAN_ALL (CAN_8|CAN_16|CAN_32)
|
||||||
|
|
||||||
|
#define LOVE_8 0x0010
|
||||||
|
#define LOVE_16 0x0020
|
||||||
|
#define LOVE_32 0x0040
|
||||||
|
|
||||||
|
#define NEED_RGB 0x0100
|
||||||
|
#define DONT_ASPECT 0x0200
|
||||||
|
|
||||||
|
#define HAVE_SCALING 0x1000
|
||||||
|
|
||||||
|
|
||||||
|
enum GFX_Modes {
|
||||||
|
GFX_8,GFX_15,GFX_16,GFX_32,GFX_NONE,
|
||||||
|
};
|
||||||
|
|
||||||
void GFX_Events(void);
|
void GFX_Events(void);
|
||||||
void GFX_SetPalette(Bitu start,Bitu count,GFX_PalEntry * entries);
|
void GFX_SetPalette(Bitu start,Bitu count,GFX_PalEntry * entries);
|
||||||
Bitu GFX_GetBestMode(Bitu bpp,Bitu & gfx_flags);
|
Bitu GFX_GetBestMode(Bitu flags);
|
||||||
|
|
||||||
Bitu GFX_GetRGB(Bit8u red,Bit8u green,Bit8u blue);
|
Bitu GFX_GetRGB(Bit8u red,Bit8u green,Bit8u blue);
|
||||||
void GFX_SetSize(Bitu width,Bitu height,Bitu bpp,double scalex,double scaley,GFX_ResetCallBack cb_reset);
|
GFX_Modes GFX_SetSize(Bitu width,Bitu height,Bitu flags,double scalex,double scaley,GFX_ResetCallBack cb_reset);
|
||||||
|
|
||||||
|
void GFX_ResetScreen(void);
|
||||||
void GFX_Start(void);
|
void GFX_Start(void);
|
||||||
void GFX_Stop(void);
|
void GFX_Stop(void);
|
||||||
void GFX_SwitchFullScreen(void);
|
void GFX_SwitchFullScreen(void);
|
||||||
bool GFX_StartUpdate(Bit8u * & pixels,Bitu & pitch);
|
bool GFX_StartUpdate(Bit8u * & pixels,Bitu & pitch);
|
||||||
void GFX_EndUpdate(void);
|
void GFX_EndUpdate(void);
|
||||||
|
|
||||||
|
/* Mouse related */
|
||||||
|
void GFX_CaptureMouse(void);
|
||||||
|
extern bool mouselocked; //true if mouse is confined to window
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -3,5 +3,5 @@ AM_CPPFLAGS = -I$(top_srcdir)/include
|
|||||||
|
|
||||||
noinst_LIBRARIES = libcpu.a
|
noinst_LIBRARIES = libcpu.a
|
||||||
libcpu_a_SOURCES = callback.cpp cpu.cpp flags.cpp modrm.cpp modrm.h core_full.cpp instructions.h \
|
libcpu_a_SOURCES = callback.cpp cpu.cpp flags.cpp modrm.cpp modrm.h core_full.cpp instructions.h \
|
||||||
paging.cpp lazyflags.h core_normal.cpp \
|
paging.cpp lazyflags.h core_normal.cpp core_simple.cpp \
|
||||||
core_dyn_x86.cpp
|
core_dyn_x86.cpp
|
@ -134,7 +134,7 @@ AM_CPPFLAGS = -I$(top_srcdir)/include
|
|||||||
|
|
||||||
noinst_LIBRARIES = libcpu.a
|
noinst_LIBRARIES = libcpu.a
|
||||||
libcpu_a_SOURCES = callback.cpp cpu.cpp flags.cpp modrm.cpp modrm.h core_full.cpp instructions.h \
|
libcpu_a_SOURCES = callback.cpp cpu.cpp flags.cpp modrm.cpp modrm.h core_full.cpp instructions.h \
|
||||||
paging.cpp lazyflags.h core_normal.cpp \
|
paging.cpp lazyflags.h core_normal.cpp core_simple.cpp \
|
||||||
core_dyn_x86.cpp
|
core_dyn_x86.cpp
|
||||||
|
|
||||||
subdir = src/cpu
|
subdir = src/cpu
|
||||||
@ -148,7 +148,8 @@ libcpu_a_AR = $(AR) cru
|
|||||||
libcpu_a_LIBADD =
|
libcpu_a_LIBADD =
|
||||||
am_libcpu_a_OBJECTS = callback.$(OBJEXT) cpu.$(OBJEXT) flags.$(OBJEXT) \
|
am_libcpu_a_OBJECTS = callback.$(OBJEXT) cpu.$(OBJEXT) flags.$(OBJEXT) \
|
||||||
modrm.$(OBJEXT) core_full.$(OBJEXT) paging.$(OBJEXT) \
|
modrm.$(OBJEXT) core_full.$(OBJEXT) paging.$(OBJEXT) \
|
||||||
core_normal.$(OBJEXT) core_dyn_x86.$(OBJEXT)
|
core_normal.$(OBJEXT) core_simple.$(OBJEXT) \
|
||||||
|
core_dyn_x86.$(OBJEXT)
|
||||||
libcpu_a_OBJECTS = $(am_libcpu_a_OBJECTS)
|
libcpu_a_OBJECTS = $(am_libcpu_a_OBJECTS)
|
||||||
|
|
||||||
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
|
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
|
||||||
@ -157,8 +158,9 @@ am__depfiles_maybe = depfiles
|
|||||||
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/callback.Po \
|
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/callback.Po \
|
||||||
@AMDEP_TRUE@ ./$(DEPDIR)/core_dyn_x86.Po \
|
@AMDEP_TRUE@ ./$(DEPDIR)/core_dyn_x86.Po \
|
||||||
@AMDEP_TRUE@ ./$(DEPDIR)/core_full.Po ./$(DEPDIR)/core_normal.Po \
|
@AMDEP_TRUE@ ./$(DEPDIR)/core_full.Po ./$(DEPDIR)/core_normal.Po \
|
||||||
@AMDEP_TRUE@ ./$(DEPDIR)/cpu.Po ./$(DEPDIR)/flags.Po \
|
@AMDEP_TRUE@ ./$(DEPDIR)/core_simple.Po ./$(DEPDIR)/cpu.Po \
|
||||||
@AMDEP_TRUE@ ./$(DEPDIR)/modrm.Po ./$(DEPDIR)/paging.Po
|
@AMDEP_TRUE@ ./$(DEPDIR)/flags.Po ./$(DEPDIR)/modrm.Po \
|
||||||
|
@AMDEP_TRUE@ ./$(DEPDIR)/paging.Po
|
||||||
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||||
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
|
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
|
||||||
CXXLD = $(CXX)
|
CXXLD = $(CXX)
|
||||||
@ -208,6 +210,7 @@ distclean-compile:
|
|||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/core_dyn_x86.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_full.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/core_normal.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/core_normal.Po@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/core_simple.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flags.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)/modrm.Po@am__quote@
|
||||||
|
@ -9,14 +9,14 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: callback.cpp,v 1.19 2004/01/07 20:23:48 qbix79 Exp $ */
|
/* $Id: callback.cpp,v 1.22 2004/08/29 11:22:37 qbix79 Exp $ */
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -67,8 +67,7 @@ void CALLBACK_Idle(void) {
|
|||||||
reg_eip=oldeip;
|
reg_eip=oldeip;
|
||||||
SegSet16(cs,oldcs);
|
SegSet16(cs,oldcs);
|
||||||
SETFLAGBIT(IF,oldIF);
|
SETFLAGBIT(IF,oldIF);
|
||||||
if (CPU_CycleLeft<300) CPU_CycleLeft=1;
|
if (CPU_Cycles>0) CPU_Cycles=0;
|
||||||
else CPU_CycleLeft-=300;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bitu default_handler(void) {
|
static Bitu default_handler(void) {
|
||||||
@ -204,12 +203,14 @@ void CALLBACK_Init(Section* sec) {
|
|||||||
/* Setup the Stop Handler */
|
/* Setup the Stop Handler */
|
||||||
call_stop=CALLBACK_Allocate();
|
call_stop=CALLBACK_Allocate();
|
||||||
CallBack_Handlers[call_stop]=stop_handler;
|
CallBack_Handlers[call_stop]=stop_handler;
|
||||||
|
CALLBACK_SetDescription(call_stop,"stop");
|
||||||
phys_writeb(CB_BASE+(call_stop<<4)+0,0xFE);
|
phys_writeb(CB_BASE+(call_stop<<4)+0,0xFE);
|
||||||
phys_writeb(CB_BASE+(call_stop<<4)+1,0x38);
|
phys_writeb(CB_BASE+(call_stop<<4)+1,0x38);
|
||||||
phys_writew(CB_BASE+(call_stop<<4)+2,call_stop);
|
phys_writew(CB_BASE+(call_stop<<4)+2,call_stop);
|
||||||
/* Setup the idle handler */
|
/* Setup the idle handler */
|
||||||
call_idle=CALLBACK_Allocate();
|
call_idle=CALLBACK_Allocate();
|
||||||
CallBack_Handlers[call_idle]=stop_handler;
|
CallBack_Handlers[call_idle]=stop_handler;
|
||||||
|
CALLBACK_SetDescription(call_idle,"idle");
|
||||||
for (i=0;i<=11;i++) phys_writeb(CB_BASE+(call_idle<<4)+i,0x90);
|
for (i=0;i<=11;i++) phys_writeb(CB_BASE+(call_idle<<4)+i,0x90);
|
||||||
phys_writeb(CB_BASE+(call_idle<<4)+12,0xFE);
|
phys_writeb(CB_BASE+(call_idle<<4)+12,0xFE);
|
||||||
phys_writeb(CB_BASE+(call_idle<<4)+13,0x38);
|
phys_writeb(CB_BASE+(call_idle<<4)+13,0x38);
|
||||||
@ -217,7 +218,7 @@ void CALLBACK_Init(Section* sec) {
|
|||||||
|
|
||||||
/* Setup all Interrupt to point to the default handler */
|
/* Setup all Interrupt to point to the default handler */
|
||||||
call_default=CALLBACK_Allocate();
|
call_default=CALLBACK_Allocate();
|
||||||
CALLBACK_Setup(call_default,&default_handler,CB_IRET);
|
CALLBACK_Setup(call_default,&default_handler,CB_IRET,"default");
|
||||||
/* Only setup default handler for first half of interrupt table */
|
/* Only setup default handler for first half of interrupt table */
|
||||||
for (i=0;i<0x40;i++) {
|
for (i=0;i<0x40;i++) {
|
||||||
real_writed(0,i*4,CALLBACK_RealPointer(call_default));
|
real_writed(0,i*4,CALLBACK_RealPointer(call_default));
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
@ -33,10 +33,11 @@
|
|||||||
#include "paging.h"
|
#include "paging.h"
|
||||||
#include "inout.h"
|
#include "inout.h"
|
||||||
|
|
||||||
#define CACHE_TOTAL (1024*1024*2)
|
#define CACHE_TOTAL (512*1024)
|
||||||
#define CACHE_MAXSIZE (4096)
|
#define CACHE_MAXSIZE (4096)
|
||||||
#define CACHE_BLOCKS (50*1024)
|
#define CACHE_BLOCKS (32*1024)
|
||||||
#define CACHE_ALIGN (16)
|
#define CACHE_ALIGN (16)
|
||||||
|
#define CACHE_PAGES (128)
|
||||||
#define DYN_HASH_SHIFT (4)
|
#define DYN_HASH_SHIFT (4)
|
||||||
#define DYN_PAGE_HASH (4096>>DYN_HASH_SHIFT)
|
#define DYN_PAGE_HASH (4096>>DYN_HASH_SHIFT)
|
||||||
#define DYN_LINKS (16)
|
#define DYN_LINKS (16)
|
||||||
@ -68,8 +69,8 @@ enum DualOps {
|
|||||||
DOP_SUB,DOP_SBB,
|
DOP_SUB,DOP_SBB,
|
||||||
DOP_CMP,DOP_XOR,
|
DOP_CMP,DOP_XOR,
|
||||||
DOP_AND,DOP_OR,
|
DOP_AND,DOP_OR,
|
||||||
DOP_MOV,
|
|
||||||
DOP_TEST,
|
DOP_TEST,
|
||||||
|
DOP_MOV,
|
||||||
DOP_XCHG,
|
DOP_XCHG,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -77,7 +78,7 @@ enum ShiftOps {
|
|||||||
SHIFT_ROL,SHIFT_ROR,
|
SHIFT_ROL,SHIFT_ROR,
|
||||||
SHIFT_RCL,SHIFT_RCR,
|
SHIFT_RCL,SHIFT_RCR,
|
||||||
SHIFT_SHL,SHIFT_SHR,
|
SHIFT_SHL,SHIFT_SHR,
|
||||||
SHIFT_SAR,
|
SHIFT_SAL,SHIFT_SAR,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum BranchTypes {
|
enum BranchTypes {
|
||||||
@ -87,19 +88,15 @@ enum BranchTypes {
|
|||||||
BR_L,BR_NL,BR_LE,BR_NLE
|
BR_L,BR_NL,BR_LE,BR_NLE
|
||||||
};
|
};
|
||||||
|
|
||||||
enum BlockType {
|
|
||||||
BT_Free=0,
|
|
||||||
BT_Normal,
|
|
||||||
BT_SingleLink,
|
|
||||||
BT_DualLink,
|
|
||||||
BT_CheckFlags,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum BlockReturn {
|
enum BlockReturn {
|
||||||
BR_Normal=0,
|
BR_Normal=0,
|
||||||
BR_Cycles,
|
BR_Cycles,
|
||||||
BR_Link1,BR_Link2,
|
BR_Link1,BR_Link2,
|
||||||
BR_Opcode,
|
BR_Opcode,
|
||||||
|
#if (C_DEBUG)
|
||||||
|
BR_OpcodeFull,
|
||||||
|
#endif
|
||||||
BR_CallBack,
|
BR_CallBack,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -153,28 +150,23 @@ struct DynState {
|
|||||||
DynReg regs[G_MAX];
|
DynReg regs[G_MAX];
|
||||||
};
|
};
|
||||||
|
|
||||||
static void dyn_releaseregs(void) {
|
static void dyn_flags_host_to_gen(void) {
|
||||||
for (Bitu i=0;i<G_MAX;i++) gen_releasereg(&DynRegs[i]);
|
gen_dop_word(DOP_MOV,true,DREG(EXIT),DREG(FLAGS));
|
||||||
}
|
gen_dop_word_imm(DOP_AND,true,DREG(EXIT),FMASK_TEST);
|
||||||
static void dyn_load_flags(void) {
|
gen_load_flags(DREG(EXIT));
|
||||||
/* Load the host flags with emulated flags */
|
gen_releasereg(DREG(EXIT));
|
||||||
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));
|
gen_releasereg(DREG(FLAGS));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dyn_save_flags(bool stored=false) {
|
static void dyn_flags_gen_to_host(void) {
|
||||||
/* Store the host flags back in emulated ones */
|
gen_save_flags(DREG(EXIT));
|
||||||
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(EXIT),FMASK_TEST);
|
||||||
gen_dop_word_imm(DOP_AND,true,DREG(FLAGS),~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_dop_word(DOP_OR,true,DREG(FLAGS),DREG(EXIT)); //flags are marked for save
|
||||||
gen_releasereg(DREG(EXIT));
|
gen_releasereg(DREG(EXIT));
|
||||||
|
gen_releasereg(DREG(FLAGS));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void dyn_savestate(DynState * state) {
|
static void dyn_savestate(DynState * state) {
|
||||||
for (Bitu i=0;i<G_MAX;i++) {
|
for (Bitu i=0;i<G_MAX;i++) {
|
||||||
state->regs[i].flags=DynRegs[i].flags;
|
state->regs[i].flags=DynRegs[i].flags;
|
||||||
@ -201,27 +193,18 @@ Bits CPU_Core_Dyn_X86_Run(void) {
|
|||||||
restart_core:
|
restart_core:
|
||||||
PhysPt ip_point=SegPhys(cs)+reg_eip;
|
PhysPt ip_point=SegPhys(cs)+reg_eip;
|
||||||
Bitu ip_page=ip_point>>12;
|
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 C_HEAVY_DEBUG
|
||||||
if (DEBUG_HeavyIsBreakpoint()) return debugCallback;
|
if (DEBUG_HeavyIsBreakpoint()) return debugCallback;
|
||||||
#endif
|
#endif
|
||||||
if (handler->flags & PFLAG_HASCODE) {
|
CodePageHandler * chandler=MakeCodePage(ip_page);
|
||||||
|
if (!chandler) return CPU_Core_Normal_Run();
|
||||||
/* Find correct Dynamic Block to run */
|
/* Find correct Dynamic Block to run */
|
||||||
chandler=(CodePageHandler *)handler;
|
|
||||||
findblock:;
|
|
||||||
CacheBlock * block=chandler->FindCacheBlock(ip_point&4095);
|
CacheBlock * block=chandler->FindCacheBlock(ip_point&4095);
|
||||||
if (!block) {
|
if (!block) {
|
||||||
cache.block.running=0;
|
block=CreateCacheBlock(chandler,ip_point,32);
|
||||||
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:
|
run_block:
|
||||||
|
cache.block.running=0;
|
||||||
BlockReturn ret=gen_runcode(block->cache.start);
|
BlockReturn ret=gen_runcode(block->cache.start);
|
||||||
switch (ret) {
|
switch (ret) {
|
||||||
case BR_Normal:
|
case BR_Normal:
|
||||||
@ -241,6 +224,12 @@ run_block:
|
|||||||
CPU_CycleLeft+=CPU_Cycles;
|
CPU_CycleLeft+=CPU_Cycles;
|
||||||
CPU_Cycles=1;
|
CPU_Cycles=1;
|
||||||
return CPU_Core_Normal_Run();
|
return CPU_Core_Normal_Run();
|
||||||
|
#if (C_DEBUG)
|
||||||
|
case BR_OpcodeFull:
|
||||||
|
CPU_CycleLeft+=CPU_Cycles;
|
||||||
|
CPU_Cycles=1;
|
||||||
|
return CPU_Core_Full_Run();
|
||||||
|
#endif
|
||||||
case BR_Link1:
|
case BR_Link1:
|
||||||
case BR_Link2:
|
case BR_Link2:
|
||||||
{
|
{
|
||||||
@ -250,31 +239,15 @@ run_block:
|
|||||||
if (temp_handler->flags & PFLAG_HASCODE) {
|
if (temp_handler->flags & PFLAG_HASCODE) {
|
||||||
block=temp_handler->FindCacheBlock(temp_ip & 4095);
|
block=temp_handler->FindCacheBlock(temp_ip & 4095);
|
||||||
if (!block) goto restart_core;
|
if (!block) goto restart_core;
|
||||||
cache_linkblocks(cache.block.running,block,ret==BR_Link2);
|
cache.block.running->LinkTo(ret==BR_Link2,block);
|
||||||
goto run_block;
|
goto run_block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
goto restart_core;
|
goto restart_core;
|
||||||
}
|
}
|
||||||
} else {
|
return 0;
|
||||||
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) {
|
void CPU_Core_Dyn_X86_Init(void) {
|
||||||
Bits i;
|
Bits i;
|
||||||
/* Setup the global registers and their flags */
|
/* Setup the global registers and their flags */
|
||||||
|
@ -1,28 +1,34 @@
|
|||||||
struct CacheBlock {
|
class CacheBlock {
|
||||||
public:
|
public:
|
||||||
|
void Clear(void);
|
||||||
|
void LinkTo(Bitu index,CacheBlock * toblock) {
|
||||||
|
assert(toblock);
|
||||||
|
link[index].to=toblock;
|
||||||
|
link[index].next=toblock->link[index].from;
|
||||||
|
toblock->link[index].from=this;
|
||||||
|
}
|
||||||
struct {
|
struct {
|
||||||
Bit16s start,end; //Where the page is the original code
|
Bit16u start,end; //Where the page is the original code
|
||||||
Bitu first,last;
|
CodePageHandler * handler; //Page containing this code
|
||||||
} page;
|
} page;
|
||||||
struct {
|
struct {
|
||||||
Bit8u * start; //Where in the cache are we
|
Bit8u * start; //Where in the cache are we
|
||||||
Bitu size;
|
Bitu size;
|
||||||
|
CacheBlock * next;
|
||||||
} cache;
|
} cache;
|
||||||
BlockType type;
|
|
||||||
CodePageHandler * code_page; //Page containing this code
|
|
||||||
CacheBlock * page_link; //For code crossing a page boundary
|
|
||||||
struct {
|
struct {
|
||||||
|
Bitu index;
|
||||||
CacheBlock * next;
|
CacheBlock * next;
|
||||||
} hash;
|
} hash;
|
||||||
CacheBlock * list_next;
|
|
||||||
struct {
|
struct {
|
||||||
CacheBlock * to[2];
|
CacheBlock * to;
|
||||||
CacheBlock * from[DYN_LINKS];
|
CacheBlock * next;
|
||||||
Bitu index;
|
CacheBlock * from;
|
||||||
} link;
|
} link[2];
|
||||||
CacheBlock * links[2];
|
CacheBlock * crossblock;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CacheBlock;
|
||||||
static struct {
|
static struct {
|
||||||
struct {
|
struct {
|
||||||
CacheBlock * first;
|
CacheBlock * first;
|
||||||
@ -31,96 +37,124 @@ static struct {
|
|||||||
CacheBlock * running;
|
CacheBlock * running;
|
||||||
} block;
|
} block;
|
||||||
Bit8u * pos;
|
Bit8u * pos;
|
||||||
CacheBlock linkblocks[2];
|
CodePageHandler * free_pages;
|
||||||
|
CodePageHandler * used_pages;
|
||||||
|
CodePageHandler * last_page;
|
||||||
} cache;
|
} cache;
|
||||||
|
|
||||||
static Bit8u cache_code_link_blocks[2][16];
|
static Bit8u cache_code_link_blocks[2][16];
|
||||||
static Bit8u cache_code[CACHE_TOTAL+CACHE_MAXSIZE];
|
static Bit8u cache_code[CACHE_TOTAL+CACHE_MAXSIZE];
|
||||||
static CacheBlock cache_blocks[CACHE_BLOCKS];
|
static CacheBlock cache_blocks[CACHE_BLOCKS];
|
||||||
|
static CacheBlock link_blocks[2];
|
||||||
static void cache_resetblock(CacheBlock * block);
|
|
||||||
|
|
||||||
class CodePageHandler :public PageHandler {
|
class CodePageHandler :public PageHandler {
|
||||||
public:
|
public:
|
||||||
CodePageHandler(PageHandler * _old_pagehandler) {
|
CodePageHandler() {}
|
||||||
|
void SetupAt(Bitu _phys_page,PageHandler * _old_pagehandler) {
|
||||||
|
phys_page=_phys_page;
|
||||||
old_pagehandler=_old_pagehandler;
|
old_pagehandler=_old_pagehandler;
|
||||||
flags=old_pagehandler->flags|PFLAG_HASCODE;
|
flags=old_pagehandler->flags|PFLAG_HASCODE;
|
||||||
flags&=~PFLAG_WRITEABLE;
|
flags&=~PFLAG_WRITEABLE;
|
||||||
|
active_blocks=0;
|
||||||
|
active_count=16;
|
||||||
memset(&hash_map,0,sizeof(hash_map));
|
memset(&hash_map,0,sizeof(hash_map));
|
||||||
memset(&write_map,0,sizeof(write_map));
|
memset(&write_map,0,sizeof(write_map));
|
||||||
}
|
}
|
||||||
void InvalidateRange(Bits start,Bits end) {
|
void InvalidateRange(Bitu start,Bitu end) {
|
||||||
Bits maps=start>>DYN_HASH_SHIFT;
|
Bits index=1+(start>>DYN_HASH_SHIFT);
|
||||||
Bits map=maps;
|
while (index>=0) {
|
||||||
Bits count=write_map[maps];
|
Bitu map=0;
|
||||||
while (map>=0 && count>0) {
|
for (Bitu count=start;count<=end;count++) map+=write_map[count];
|
||||||
CacheBlock * block=hash_map[map];
|
if (!map) return;
|
||||||
CacheBlock * * where=&hash_map[map];
|
CacheBlock * block=hash_map[index];
|
||||||
while (block) {
|
while (block) {
|
||||||
CacheBlock * nextblock=block->hash.next;
|
CacheBlock * nextblock=block->hash.next;
|
||||||
if (start<=block->page.end && end>=block->page.start) {
|
if (start<=block->page.end && end>=block->page.start)
|
||||||
for (Bitu i=block->page.first;i<=block->page.last;i++) write_map[i]--;
|
block->Clear();
|
||||||
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;
|
block=nextblock;
|
||||||
}
|
}
|
||||||
map--;
|
index--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void writeb(PhysPt addr,Bitu val){
|
void writeb(PhysPt addr,Bitu val){
|
||||||
if (val!=host_readb(hostmem+(addr&4095))) {
|
addr&=4095;
|
||||||
InvalidateRange(addr&4095,addr&4095);
|
host_writeb(hostmem+addr,val);
|
||||||
host_writeb(hostmem+(addr&4095),val);
|
if (!*(Bit8u*)&write_map[addr]) {
|
||||||
}
|
if (active_blocks) return;
|
||||||
|
active_count--;
|
||||||
|
if (!active_count) Release();
|
||||||
|
} else InvalidateRange(addr,addr);
|
||||||
}
|
}
|
||||||
void writew(PhysPt addr,Bitu val){
|
void writew(PhysPt addr,Bitu val){
|
||||||
if (val!=host_readw(hostmem+(addr&4095))) {
|
addr&=4095;
|
||||||
InvalidateRange(addr&4095,(addr&4095)+1);
|
host_writew(hostmem+addr,val);
|
||||||
host_writew(hostmem+(addr&4095),val);
|
if (!*(Bit16u*)&write_map[addr]) {
|
||||||
}
|
if (active_blocks) return;
|
||||||
|
active_count--;
|
||||||
|
if (!active_count) Release();
|
||||||
|
} else InvalidateRange(addr,addr+1);
|
||||||
}
|
}
|
||||||
void writed(PhysPt addr,Bitu val){
|
void writed(PhysPt addr,Bitu val){
|
||||||
if (val!=host_readd(hostmem+(addr&4095))) {
|
addr&=4095;
|
||||||
InvalidateRange(addr&4095,(addr&4095)+3);
|
host_writed(hostmem+addr,val);
|
||||||
host_writed(hostmem+(addr&4095),val);
|
if (!*(Bit32u*)&write_map[addr]) {
|
||||||
}
|
if (active_blocks) return;
|
||||||
|
active_count--;
|
||||||
|
if (!active_count) Release();
|
||||||
|
} else InvalidateRange(addr,addr+3);
|
||||||
}
|
}
|
||||||
void AddCacheBlock(CacheBlock * block) {
|
void AddCacheBlock(CacheBlock * block) {
|
||||||
Bit16u first,last;
|
Bitu index=1+(block->page.start>>DYN_HASH_SHIFT);
|
||||||
if (block->page.start<0) first=0;
|
block->hash.next=hash_map[index];
|
||||||
else first=block->page.start>>DYN_HASH_SHIFT;
|
block->hash.index=index;
|
||||||
block->hash.next=hash_map[first];
|
hash_map[index]=block;
|
||||||
hash_map[first]=block;
|
block->page.handler=this;
|
||||||
if (block->page.end>=4096) last=DYN_PAGE_HASH-1;
|
active_blocks++;
|
||||||
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 AddCrossBlock(CacheBlock * block) {
|
||||||
|
block->hash.next=hash_map[0];
|
||||||
|
block->hash.index=0;
|
||||||
|
hash_map[0]=block;
|
||||||
|
block->page.handler=this;
|
||||||
|
active_blocks++;
|
||||||
}
|
}
|
||||||
void DelCacheBlock(CacheBlock * block) {
|
void DelCacheBlock(CacheBlock * block) {
|
||||||
CacheBlock * * where=&hash_map[block->page.first];
|
active_blocks--;
|
||||||
while (*where) {
|
active_count=16;
|
||||||
if (*where==block) {
|
CacheBlock * * where=&hash_map[block->hash.index];
|
||||||
*where=block->hash.next;
|
while (*where!=block) {
|
||||||
break;
|
|
||||||
}
|
|
||||||
where=&((*where)->hash.next);
|
where=&((*where)->hash.next);
|
||||||
|
//Will crash if a block isn't found, which should never happen.
|
||||||
}
|
}
|
||||||
for (Bitu i=block->page.first;i<=block->page.last;i++) {
|
*where=block->hash.next;
|
||||||
write_map[i]--;
|
for (Bitu i=block->page.start;i<=block->page.end;i++) {
|
||||||
|
if (write_map[i]) write_map[i]--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void Release(void) {
|
||||||
|
MEM_SetPageHandler(phys_page,1,old_pagehandler);
|
||||||
|
PAGING_ClearTLB();
|
||||||
|
if (prev) prev->next=next;
|
||||||
|
else cache.used_pages=next;
|
||||||
|
if (next) next->prev=prev;
|
||||||
|
else cache.last_page=prev;
|
||||||
|
next=cache.free_pages;
|
||||||
|
cache.free_pages=this;
|
||||||
|
prev=0;
|
||||||
|
}
|
||||||
|
void ClearRelease(void) {
|
||||||
|
for (Bitu index=0;index<(1+DYN_PAGE_HASH);index++) {
|
||||||
|
CacheBlock * block=hash_map[index];
|
||||||
|
while (block) {
|
||||||
|
CacheBlock * nextblock=block->hash.next;
|
||||||
|
block->page.handler=0; //No need, full clear
|
||||||
|
block->Clear();
|
||||||
|
block=nextblock;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Release();
|
||||||
|
}
|
||||||
CacheBlock * FindCacheBlock(Bitu start) {
|
CacheBlock * FindCacheBlock(Bitu start) {
|
||||||
CacheBlock * block=hash_map[start>>DYN_HASH_SHIFT];
|
CacheBlock * block=hash_map[1+(start>>DYN_HASH_SHIFT)];
|
||||||
while (block) {
|
while (block) {
|
||||||
if (block->page.start==start) return block;
|
if (block->page.start==start) return block;
|
||||||
block=block->hash.next;
|
block=block->hash.next;
|
||||||
@ -131,133 +165,153 @@ public:
|
|||||||
hostmem=old_pagehandler->GetHostPt(phys_page);
|
hostmem=old_pagehandler->GetHostPt(phys_page);
|
||||||
return hostmem;
|
return hostmem;
|
||||||
}
|
}
|
||||||
|
public:
|
||||||
|
Bit8u write_map[4096];
|
||||||
|
CodePageHandler * next, * prev;
|
||||||
private:
|
private:
|
||||||
PageHandler * old_pagehandler;
|
PageHandler * old_pagehandler;
|
||||||
CacheBlock * hash_map[DYN_PAGE_HASH];
|
CacheBlock * hash_map[1+DYN_PAGE_HASH];
|
||||||
Bit8u write_map[DYN_PAGE_HASH];
|
Bitu active_blocks;
|
||||||
|
Bitu active_count;
|
||||||
HostPt hostmem;
|
HostPt hostmem;
|
||||||
|
Bitu phys_page;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static CodePageHandler * MakeCodePage(Bitu lin_page) {
|
||||||
|
mem_readb(lin_page << 12); //Ensure page contains memory
|
||||||
|
PageHandler * handler=paging.tlb.handler[lin_page];
|
||||||
|
if (handler->flags & PFLAG_HASCODE) return ( CodePageHandler *)handler;
|
||||||
|
if (handler->flags & PFLAG_NOCODE) {
|
||||||
|
LOG_MSG("DYNX86:Can't run code in this page");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Bitu phys_page=lin_page;
|
||||||
|
if (!PAGING_MakePhysPage(phys_page)) {
|
||||||
|
LOG_MSG("DYNX86:Can't find physpage");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/* Find a free CodePage */
|
||||||
|
if (!cache.free_pages) {
|
||||||
|
cache.used_pages->ClearRelease();
|
||||||
|
}
|
||||||
|
CodePageHandler * cpagehandler=cache.free_pages;
|
||||||
|
cache.free_pages=cache.free_pages->next;
|
||||||
|
cpagehandler->prev=cache.last_page;
|
||||||
|
cpagehandler->next=0;
|
||||||
|
if (cache.last_page) cache.last_page->next=cpagehandler;
|
||||||
|
cache.last_page=cpagehandler;
|
||||||
|
if (!cache.used_pages) cache.used_pages=cpagehandler;
|
||||||
|
cpagehandler->SetupAt(phys_page,handler);
|
||||||
|
MEM_SetPageHandler(phys_page,1,cpagehandler);
|
||||||
|
PAGING_UnlinkPages(lin_page,1);
|
||||||
|
return cpagehandler;
|
||||||
|
}
|
||||||
|
|
||||||
static INLINE void cache_addunsedblock(CacheBlock * block) {
|
static INLINE void cache_addunsedblock(CacheBlock * block) {
|
||||||
block->list_next=cache.block.free;
|
block->cache.next=cache.block.free;
|
||||||
cache.block.free=block;
|
cache.block.free=block;
|
||||||
}
|
}
|
||||||
|
|
||||||
static CacheBlock * cache_getblock(void) {
|
static CacheBlock * cache_getblock(void) {
|
||||||
CacheBlock * ret=cache.block.free;
|
CacheBlock * ret=cache.block.free;
|
||||||
if (!ret) E_Exit("Ran out of CacheBlocks" );
|
if (!ret) E_Exit("Ran out of CacheBlocks" );
|
||||||
cache.block.free=ret->list_next;
|
cache.block.free=ret->cache.next;
|
||||||
|
ret->cache.next=0;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static INLINE void cache_clearlinkfrom(CacheBlock * block,CacheBlock * from) {
|
void CacheBlock::Clear(void) {
|
||||||
for (Bitu i=0;i<DYN_LINKS;i++) {
|
Bitu ind;
|
||||||
if (block->link.from[i]==from) block->link.from[i]=0;
|
/* Check if this is not a cross page block */
|
||||||
|
if (hash.index) for (ind=0;ind<2;ind++) {
|
||||||
|
CacheBlock * fromlink=link[ind].from;
|
||||||
|
link[ind].from=0;
|
||||||
|
while (fromlink) {
|
||||||
|
CacheBlock * nextlink=fromlink->link[ind].next;
|
||||||
|
fromlink->link[ind].next=0;
|
||||||
|
fromlink->link[ind].to=&link_blocks[ind];
|
||||||
|
fromlink=nextlink;
|
||||||
|
}
|
||||||
|
if (link[ind].to!=&link_blocks[ind]) {
|
||||||
|
CacheBlock * * wherelink=&link[ind].to->link[ind].from;
|
||||||
|
while (*wherelink!=this) {
|
||||||
|
wherelink=&(*wherelink)->link[ind].next;
|
||||||
|
}
|
||||||
|
*wherelink=(*wherelink)->link[ind].next;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
cache_addunsedblock(this);
|
||||||
|
if (crossblock) {
|
||||||
|
crossblock->crossblock=0;
|
||||||
|
crossblock->Clear();
|
||||||
|
crossblock=0;
|
||||||
|
}
|
||||||
|
if (page.handler) {
|
||||||
|
page.handler->DelCacheBlock(this);
|
||||||
|
page.handler=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) {
|
static CacheBlock * cache_openblock(void) {
|
||||||
CacheBlock * block=cache.block.active;
|
CacheBlock * block=cache.block.active;
|
||||||
/* check for enough space in this block */
|
/* check for enough space in this block */
|
||||||
Bitu size=block->cache.size;
|
Bitu size=block->cache.size;
|
||||||
CacheBlock * nextblock=block->list_next;
|
CacheBlock * nextblock=block->cache.next;
|
||||||
|
if (block->page.handler)
|
||||||
|
block->Clear();
|
||||||
while (size<CACHE_MAXSIZE) {
|
while (size<CACHE_MAXSIZE) {
|
||||||
if (!nextblock) goto skipresize;
|
if (!nextblock)
|
||||||
|
goto skipresize;
|
||||||
size+=nextblock->cache.size;
|
size+=nextblock->cache.size;
|
||||||
CacheBlock * tempblock=nextblock->list_next;
|
CacheBlock * tempblock=nextblock->cache.next;
|
||||||
if (nextblock->type!=BT_Free) cache_resetblock(nextblock);
|
if (nextblock->page.handler)
|
||||||
|
nextblock->Clear();
|
||||||
cache_addunsedblock(nextblock);
|
cache_addunsedblock(nextblock);
|
||||||
nextblock=tempblock;
|
nextblock=tempblock;
|
||||||
}
|
}
|
||||||
skipresize:
|
skipresize:
|
||||||
block->cache.size=size;
|
block->cache.size=size;
|
||||||
block->list_next=nextblock;
|
block->cache.next=nextblock;
|
||||||
cache.pos=block->cache.start;
|
cache.pos=block->cache.start;
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cache_closeblock(BlockType type) {
|
static void cache_closeblock(void) {
|
||||||
CacheBlock * block=cache.block.active;
|
CacheBlock * block=cache.block.active;
|
||||||
/* Setup some structures in the block determined by type */
|
block->link[0].to=&link_blocks[0];
|
||||||
block->type=type;
|
block->link[1].to=&link_blocks[1];
|
||||||
switch (type) {
|
block->link[0].from=0;
|
||||||
case BT_Normal:
|
block->link[1].from=0;
|
||||||
break;
|
block->link[0].next=0;
|
||||||
case BT_SingleLink:
|
block->link[1].next=0;
|
||||||
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 */
|
/* Close the block with correct alignments */
|
||||||
Bitu written=cache.pos-block->cache.start;
|
Bitu written=cache.pos-block->cache.start;
|
||||||
if (written>block->cache.size) {
|
if (written>block->cache.size) {
|
||||||
if (!block->list_next) {
|
if (!block->cache.next) {
|
||||||
if (written>block->cache.size+CACHE_MAXSIZE) E_Exit("CacheBlock overrun");
|
if (written>block->cache.size+CACHE_MAXSIZE) E_Exit("CacheBlock overrun 1 %d",written-block->cache.size);
|
||||||
} else E_Exit("CacheBlock overrun");
|
} else E_Exit("CacheBlock overrun 2 written %d size %d",written,block->cache.size);
|
||||||
} else {
|
} else {
|
||||||
Bitu new_size;
|
Bitu new_size;
|
||||||
Bitu left=block->cache.size-written;
|
Bitu left=block->cache.size-written;
|
||||||
/* Smaller than cache align then don't bother to resize */
|
/* Smaller than cache align then don't bother to resize */
|
||||||
if (left>CACHE_ALIGN) {
|
if (left>CACHE_ALIGN) {
|
||||||
new_size=((written-1)|(CACHE_ALIGN-1))+1;
|
new_size=((written-1)|(CACHE_ALIGN-1))+1;
|
||||||
} else new_size=block->cache.size;
|
|
||||||
CacheBlock * newblock=cache_getblock();
|
CacheBlock * newblock=cache_getblock();
|
||||||
newblock->cache.start=block->cache.start+new_size;
|
newblock->cache.start=block->cache.start+new_size;
|
||||||
newblock->cache.size=block->cache.size-new_size;
|
newblock->cache.size=block->cache.size-new_size;
|
||||||
newblock->list_next=block->list_next;
|
newblock->cache.next=block->cache.next;
|
||||||
newblock->type=BT_Free;
|
block->cache.next=newblock;
|
||||||
block->cache.size=new_size;
|
block->cache.size=new_size;
|
||||||
block->list_next=newblock;
|
}
|
||||||
}
|
}
|
||||||
/* Advance the active block pointer */
|
/* Advance the active block pointer */
|
||||||
if (!block->list_next) {
|
if (!block->cache.next) {
|
||||||
DYN_LOG("Cache full restarting");
|
// LOG_MSG("Cache full restarting");
|
||||||
cache.block.active=cache.block.first;
|
cache.block.active=cache.block.first;
|
||||||
} else {
|
} else {
|
||||||
cache.block.active=block->list_next;
|
cache.block.active=block->cache.next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,20 +337,29 @@ static void cache_init(void) {
|
|||||||
memset(&cache_blocks,0,sizeof(cache_blocks));
|
memset(&cache_blocks,0,sizeof(cache_blocks));
|
||||||
cache.block.free=&cache_blocks[0];
|
cache.block.free=&cache_blocks[0];
|
||||||
for (i=0;i<CACHE_BLOCKS-1;i++) {
|
for (i=0;i<CACHE_BLOCKS-1;i++) {
|
||||||
cache_blocks[i].list_next=&cache_blocks[i+1];
|
cache_blocks[i].link[0].to=(CacheBlock *)1;
|
||||||
cache_blocks[i].link.to[0]=&cache.linkblocks[0];
|
cache_blocks[i].link[1].to=(CacheBlock *)1;
|
||||||
cache_blocks[i].link.to[1]=&cache.linkblocks[1];
|
cache_blocks[i].cache.next=&cache_blocks[i+1];
|
||||||
}
|
}
|
||||||
CacheBlock * block=cache_getblock();
|
CacheBlock * block=cache_getblock();
|
||||||
cache.block.first=block;
|
cache.block.first=block;
|
||||||
cache.block.active=block;
|
cache.block.active=block;
|
||||||
block->cache.start=&cache_code[0];
|
block->cache.start=&cache_code[0];
|
||||||
block->cache.size=CACHE_TOTAL;
|
block->cache.size=CACHE_TOTAL;
|
||||||
block->list_next=0; //Last block in the list
|
block->cache.next=0; //Last block in the list
|
||||||
cache.pos=&cache_code_link_blocks[0][0];
|
cache.pos=&cache_code_link_blocks[0][0];
|
||||||
cache.linkblocks[0].cache.start=cache.pos;
|
link_blocks[0].cache.start=cache.pos;
|
||||||
gen_return(BR_Link1);
|
gen_return(BR_Link1);
|
||||||
cache.pos=&cache_code_link_blocks[1][0];
|
cache.pos=&cache_code_link_blocks[1][0];
|
||||||
cache.linkblocks[1].cache.start=cache.pos;
|
link_blocks[1].cache.start=cache.pos;
|
||||||
gen_return(BR_Link2);
|
gen_return(BR_Link2);
|
||||||
|
cache.free_pages=0;
|
||||||
|
cache.last_page=0;
|
||||||
|
cache.used_pages=0;
|
||||||
|
/* Setup the code pages */
|
||||||
|
for (i=0;i<CACHE_PAGES-1;i++) {
|
||||||
|
CodePageHandler * newpage=new CodePageHandler();
|
||||||
|
newpage->next=cache.free_pages;
|
||||||
|
cache.free_pages=newpage;
|
||||||
|
}
|
||||||
}
|
}
|
File diff suppressed because it is too large
Load Diff
@ -1,57 +1,57 @@
|
|||||||
static Bitu dyn_helper_divb(Bit8u val) {
|
static bool dyn_helper_divb(Bit8u val) {
|
||||||
if (!val) return 1;
|
if (!val) return CPU_PrepareException(0,0);
|
||||||
Bitu quo=reg_ax / val;
|
Bitu quo=reg_ax / val;
|
||||||
reg_ah=(Bit8u)(reg_ax % val);
|
reg_ah=(Bit8u)(reg_ax % val);
|
||||||
reg_al=(Bit8u)quo;
|
reg_al=(Bit8u)quo;
|
||||||
if (quo>0xff) return 1;
|
if (quo>0xff) return CPU_PrepareException(0,0);
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bitu dyn_helper_idivb(Bit8s val) {
|
static bool dyn_helper_idivb(Bit8s val) {
|
||||||
if (!val) return 1;
|
if (!val) return CPU_PrepareException(0,0);
|
||||||
Bits quo=(Bit16s)reg_ax / val;
|
Bits quo=(Bit16s)reg_ax / val;
|
||||||
reg_ah=(Bit8s)((Bit16s)reg_ax % val);
|
reg_ah=(Bit8s)((Bit16s)reg_ax % val);
|
||||||
reg_al=(Bit8s)quo;
|
reg_al=(Bit8s)quo;
|
||||||
if (quo!=(Bit8s)reg_al) return 1;
|
if (quo!=(Bit8s)reg_al) return CPU_PrepareException(0,0);
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bitu dyn_helper_divw(Bit16u val) {
|
static bool dyn_helper_divw(Bit16u val) {
|
||||||
if (!val) return 1;
|
if (!val) return CPU_PrepareException(0,0);
|
||||||
Bitu num=(reg_dx<<16)|reg_ax;
|
Bitu num=(reg_dx<<16)|reg_ax;
|
||||||
Bitu quo=num/val;
|
Bitu quo=num/val;
|
||||||
reg_dx=(Bit16u)(num % val);
|
reg_dx=(Bit16u)(num % val);
|
||||||
reg_ax=(Bit16u)quo;
|
reg_ax=(Bit16u)quo;
|
||||||
if (quo!=reg_ax) return 1;
|
if (quo!=reg_ax) return CPU_PrepareException(0,0);
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bitu dyn_helper_idivw(Bit16s val) {
|
static bool dyn_helper_idivw(Bit16s val) {
|
||||||
if (!val) return 1;
|
if (!val) return CPU_PrepareException(0,0);
|
||||||
Bits num=(reg_dx<<16)|reg_ax;
|
Bits num=(reg_dx<<16)|reg_ax;
|
||||||
Bits quo=num/val;
|
Bits quo=num/val;
|
||||||
reg_dx=(Bit16s)(num % val);
|
reg_dx=(Bit16s)(num % val);
|
||||||
reg_ax=(Bit16s)quo;
|
reg_ax=(Bit16s)quo;
|
||||||
if (quo!=(Bit16s)reg_ax) return 1;
|
if (quo!=(Bit16s)reg_ax) return CPU_PrepareException(0,0);
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bitu dyn_helper_divd(Bit32u val) {
|
static bool dyn_helper_divd(Bit32u val) {
|
||||||
if (!val) return 1;
|
if (!val) return CPU_PrepareException(0,0);
|
||||||
Bit64u num=(((Bit64u)reg_edx)<<32)|reg_eax;
|
Bit64u num=(((Bit64u)reg_edx)<<32)|reg_eax;
|
||||||
Bit64u quo=num/val;
|
Bit64u quo=num/val;
|
||||||
reg_edx=(Bit32u)(num % val);
|
reg_edx=(Bit32u)(num % val);
|
||||||
reg_eax=(Bit32u)quo;
|
reg_eax=(Bit32u)quo;
|
||||||
if (quo!=(Bit64u)reg_eax) return 1;
|
if (quo!=(Bit64u)reg_eax) return CPU_PrepareException(0,0);
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bitu dyn_helper_idivd(Bit32s val) {
|
static bool dyn_helper_idivd(Bit32s val) {
|
||||||
if (!val) return 1;
|
if (!val) return CPU_PrepareException(0,0);
|
||||||
Bit64s num=(((Bit64u)reg_edx)<<32)|reg_eax;
|
Bit64s num=(((Bit64u)reg_edx)<<32)|reg_eax;
|
||||||
Bit64s quo=num/val;
|
Bit64s quo=num/val;
|
||||||
reg_edx=(Bit32s)(num % val);
|
reg_edx=(Bit32s)(num % val);
|
||||||
reg_eax=(Bit32s)(quo);
|
reg_eax=(Bit32s)(quo);
|
||||||
if (quo!=(Bit64s)((Bit32s)reg_eax)) return 1;
|
if (quo!=(Bit64s)((Bit32s)reg_eax)) return CPU_PrepareException(0,0);
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
@ -32,8 +32,8 @@ static void gen_init(void);
|
|||||||
#define X86_REG_MASK(_REG_) (1 << X86_REG_ ## _REG_)
|
#define X86_REG_MASK(_REG_) (1 << X86_REG_ ## _REG_)
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
|
bool flagsactive;
|
||||||
Bitu last_used;
|
Bitu last_used;
|
||||||
Bitu stored_flags;
|
|
||||||
GenReg * regs[X86_REGS];
|
GenReg * regs[X86_REGS];
|
||||||
} x86gen;
|
} x86gen;
|
||||||
|
|
||||||
@ -98,13 +98,13 @@ static BlockReturn gen_runcode(Bit8u * code) {
|
|||||||
push edi
|
push edi
|
||||||
mov ebx,[reg_flags]
|
mov ebx,[reg_flags]
|
||||||
and ebx,FMASK_TEST
|
and ebx,FMASK_TEST
|
||||||
|
push offset(return_address)
|
||||||
push ebx
|
push ebx
|
||||||
popfd
|
jmp eax
|
||||||
call eax
|
|
||||||
/* Restore the flags */
|
/* Restore the flags */
|
||||||
pushfd
|
return_address:
|
||||||
|
/* return here with flags in ecx */
|
||||||
and dword ptr [reg_flags],~FMASK_TEST
|
and dword ptr [reg_flags],~FMASK_TEST
|
||||||
pop ecx
|
|
||||||
and ecx,FMASK_TEST
|
and ecx,FMASK_TEST
|
||||||
or [reg_flags],ecx
|
or [reg_flags],ecx
|
||||||
pop edi
|
pop edi
|
||||||
@ -114,23 +114,19 @@ static BlockReturn gen_runcode(Bit8u * code) {
|
|||||||
mov [retval],eax
|
mov [retval],eax
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
register Bit32u tempflags=reg_flags & FMASK_TEST;
|
||||||
__asm__ volatile (
|
__asm__ volatile (
|
||||||
"movl %1,%%esi \n"
|
|
||||||
"andl %2,%%esi \n"
|
|
||||||
"pushl %%ebp \n"
|
"pushl %%ebp \n"
|
||||||
"pushl %%esi \n"
|
"pushl $(run_return_adress) \n"
|
||||||
"popfl \n"
|
"pushl %2 \n"
|
||||||
"calll *%4 \n"
|
"jmp *%3 \n"
|
||||||
|
"run_return_adress: \n"
|
||||||
"popl %%ebp \n"
|
"popl %%ebp \n"
|
||||||
"pushfl \n"
|
:"=a" (retval), "=c" (tempflags)
|
||||||
"andl %3,(%1) \n"
|
:"r" (tempflags),"r" (code)
|
||||||
"popl %%esi \n"
|
:"%edx","%ebx","%edi","%esi","cc","memory"
|
||||||
"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"
|
|
||||||
);
|
);
|
||||||
|
reg_flags=(reg_flags & ~FMASK_TEST) | (tempflags & FMASK_TEST);
|
||||||
#endif
|
#endif
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
@ -232,28 +228,23 @@ static void gen_synchreg(DynReg * dnew,DynReg * dsynch) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gen_storeflags(void) {
|
static void gen_needflags(void) {
|
||||||
if (!x86gen.stored_flags) {
|
if (!x86gen.flagsactive) {
|
||||||
cache_addb(0x9c); //PUSHFD
|
x86gen.flagsactive=true;
|
||||||
|
cache_addb(0x9d); //POPFD
|
||||||
}
|
}
|
||||||
x86gen.stored_flags++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gen_restoreflags(bool noreduce=false) {
|
static void gen_protectflags(void) {
|
||||||
if (noreduce) {
|
if (x86gen.flagsactive) {
|
||||||
cache_addb(0x9d);
|
x86gen.flagsactive=false;
|
||||||
return;
|
cache_addb(0x9c); //PUSHFD
|
||||||
}
|
}
|
||||||
if (x86gen.stored_flags) {
|
|
||||||
x86gen.stored_flags--;
|
|
||||||
if (!x86gen.stored_flags)
|
|
||||||
cache_addb(0x9d); //POPFD
|
|
||||||
} else IllegalOption();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gen_reinit(void) {
|
static void gen_reinit(void) {
|
||||||
x86gen.last_used=0;
|
x86gen.last_used=0;
|
||||||
x86gen.stored_flags=0;
|
x86gen.flagsactive=false;
|
||||||
for (Bitu i=0;i<X86_REGS;i++) {
|
for (Bitu i=0;i<X86_REGS;i++) {
|
||||||
x86gen.regs[i]->dynreg=0;
|
x86gen.regs[i]->dynreg=0;
|
||||||
}
|
}
|
||||||
@ -483,55 +474,32 @@ static void gen_sop_word(SingleOps op,bool dword,DynReg * dr1) {
|
|||||||
dr1->flags|=DYNFLG_CHANGED;
|
dr1->flags|=DYNFLG_CHANGED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gen_shift_byte(ShiftOps op,DynReg * drecx,DynReg * dr1,Bit8u di1) {
|
static void gen_shift_byte_cl(Bitu op,DynReg * dr1,Bit8u di1,DynReg * drecx) {
|
||||||
ForceDynReg(x86gen.regs[X86_REG_ECX],drecx);
|
ForceDynReg(x86gen.regs[X86_REG_ECX],drecx);
|
||||||
GenReg * gr1=FindDynReg(dr1);
|
GenReg * gr1=FindDynReg(dr1);
|
||||||
switch (op) {
|
cache_addw(0xc0d2+(((Bit16u)op) << 11)+ ((gr1->index+di1)<<8));
|
||||||
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;
|
dr1->flags|=DYNFLG_CHANGED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gen_shift_word(ShiftOps op,DynReg * drecx,bool dword,DynReg * dr1) {
|
static void gen_shift_byte_imm(Bitu op,DynReg * dr1,Bit8u di1,Bit8u imm) {
|
||||||
ForceDynReg(x86gen.regs[X86_REG_ECX],drecx);
|
|
||||||
GenReg * gr1=FindDynReg(dr1);
|
GenReg * gr1=FindDynReg(dr1);
|
||||||
if (!dword) cache_addb(0x66);
|
cache_addw(0xc0c0+(((Bit16u)op) << 11) + ((gr1->index+di1)<<8));
|
||||||
switch (op) {
|
cache_addb(imm);
|
||||||
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;
|
dr1->flags|=DYNFLG_CHANGED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gen_shift_word_imm(ShiftOps op,bool dword,DynReg * dr1,Bit8u imm) {
|
static void gen_shift_word_cl(Bitu op,bool dword,DynReg * dr1,DynReg * drecx) {
|
||||||
|
ForceDynReg(x86gen.regs[X86_REG_ECX],drecx);
|
||||||
GenReg * gr1=FindDynReg(dr1);
|
GenReg * gr1=FindDynReg(dr1);
|
||||||
if (!dword) cache_addb(0x66);
|
if (!dword) cache_addb(0x66);
|
||||||
switch (op) {
|
cache_addw(0xc0d3+(((Bit16u)op) << 11) + ((gr1->index)<<8));
|
||||||
case SHIFT_ROL:cache_addw(0xc0c1+((gr1->index)<<8));break;
|
dr1->flags|=DYNFLG_CHANGED;
|
||||||
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;
|
static void gen_shift_word_imm(Bitu op,bool dword,DynReg * dr1,Bit8u imm) {
|
||||||
case SHIFT_SHL:cache_addw(0xe0c1+((gr1->index)<<8));break;
|
GenReg * gr1=FindDynReg(dr1);
|
||||||
case SHIFT_SHR:cache_addw(0xe8c1+((gr1->index)<<8));break;
|
if (!dword) cache_addb(0x66);
|
||||||
case SHIFT_SAR:cache_addw(0xf8c1+((gr1->index)<<8));break;
|
cache_addw(0xc0c1+(((Bit16u)op) << 11) + ((gr1->index)<<8));
|
||||||
default:
|
|
||||||
IllegalOption();
|
|
||||||
}
|
|
||||||
cache_addb(imm);
|
cache_addb(imm);
|
||||||
dr1->flags|=DYNFLG_CHANGED;
|
dr1->flags|=DYNFLG_CHANGED;
|
||||||
}
|
}
|
||||||
@ -604,7 +572,7 @@ static void gen_call_function(void * func,char * ops,...) {
|
|||||||
x86gen.regs[X86_REG_EAX]->Clear();
|
x86gen.regs[X86_REG_EAX]->Clear();
|
||||||
x86gen.regs[X86_REG_EAX]->notusable=true;;
|
x86gen.regs[X86_REG_EAX]->notusable=true;;
|
||||||
/* Save the flags */
|
/* Save the flags */
|
||||||
gen_storeflags();
|
gen_protectflags();
|
||||||
/* Scan for the amount of params */
|
/* Scan for the amount of params */
|
||||||
if (ops) {
|
if (ops) {
|
||||||
va_list params;
|
va_list params;
|
||||||
@ -704,7 +672,6 @@ static void gen_call_function(void * func,char * ops,...) {
|
|||||||
}
|
}
|
||||||
dynreg->flags|=DYNFLG_CHANGED;
|
dynreg->flags|=DYNFLG_CHANGED;
|
||||||
}
|
}
|
||||||
gen_restoreflags();
|
|
||||||
/* Restore EAX registers to be used again */
|
/* Restore EAX registers to be used again */
|
||||||
x86gen.regs[X86_REG_EAX]->notusable=false;
|
x86gen.regs[X86_REG_EAX]->notusable=false;
|
||||||
}
|
}
|
||||||
@ -717,6 +684,11 @@ static Bit8u * gen_create_branch(BranchTypes type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void gen_fill_branch(Bit8u * data,Bit8u * from=cache.pos) {
|
static void gen_fill_branch(Bit8u * data,Bit8u * from=cache.pos) {
|
||||||
|
#if C_DEBUG
|
||||||
|
Bits len=from-data;
|
||||||
|
if (len<0) len=-len;
|
||||||
|
if (len>126) LOG_MSG("BIg jump %d",len);
|
||||||
|
#endif
|
||||||
*data=(from-data-1);
|
*data=(from-data-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -747,17 +719,20 @@ static void gen_jmp_ptr(void * ptr,Bits imm=0) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gen_save_flags(DynReg * dynreg,bool stored) {
|
static void gen_save_flags(DynReg * dynreg) {
|
||||||
|
if (x86gen.flagsactive) IllegalOption();
|
||||||
GenReg * genreg=FindDynReg(dynreg);
|
GenReg * genreg=FindDynReg(dynreg);
|
||||||
if (!stored) cache_addb(0x9c); //Pushfd
|
cache_addb(0x8b); //MOV REG,[esp]
|
||||||
cache_addb(0x58+genreg->index); //POP 32 REG
|
cache_addw(0x2404+(genreg->index << 3));
|
||||||
dynreg->flags|=DYNFLG_CHANGED;
|
dynreg->flags|=DYNFLG_CHANGED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gen_load_flags(DynReg * dynreg) {
|
static void gen_load_flags(DynReg * dynreg) {
|
||||||
|
if (x86gen.flagsactive) IllegalOption();
|
||||||
|
cache_addw(0xc483); //ADD ESP,4
|
||||||
|
cache_addb(0x4);
|
||||||
GenReg * genreg=FindDynReg(dynreg);
|
GenReg * genreg=FindDynReg(dynreg);
|
||||||
cache_addb(0x50+genreg->index); //PUSH 32
|
cache_addb(0x50+genreg->index); //PUSH 32
|
||||||
cache_addb(0x9d); //POPFD
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gen_save_host_direct(void * data,Bits imm) {
|
static void gen_save_host_direct(void * data,Bits imm) {
|
||||||
@ -781,9 +756,11 @@ static void gen_load_host(void * data,DynReg * dr1,Bitu size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void gen_return(BlockReturn retcode) {
|
static void gen_return(BlockReturn retcode) {
|
||||||
cache_addb(0xb8);
|
gen_protectflags();
|
||||||
|
cache_addb(0x59); //POP ECX, the flags
|
||||||
|
cache_addb(0xb8); //MOV EAX, retcode
|
||||||
cache_addd(retcode);
|
cache_addd(retcode);
|
||||||
cache_addb(0xc3);
|
cache_addb(0xc3); //RET
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gen_init(void) {
|
static void gen_init(void) {
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
@ -30,7 +30,7 @@ static void dyn_string(STRING_OP op) {
|
|||||||
DynReg * si_base=decode.segprefix ? decode.segprefix : DREG(DS);
|
DynReg * si_base=decode.segprefix ? decode.segprefix : DREG(DS);
|
||||||
DynReg * di_base=DREG(ES);
|
DynReg * di_base=DREG(ES);
|
||||||
DynReg * tmp_reg;bool usesi;bool usedi;
|
DynReg * tmp_reg;bool usesi;bool usedi;
|
||||||
gen_storeflags();
|
gen_protectflags();
|
||||||
if (decode.rep) {
|
if (decode.rep) {
|
||||||
gen_dop_word_imm(DOP_SUB,true,DREG(CYCLES),decode.cycles);
|
gen_dop_word_imm(DOP_SUB,true,DREG(CYCLES),decode.cycles);
|
||||||
gen_releasereg(DREG(CYCLES));
|
gen_releasereg(DREG(CYCLES));
|
||||||
@ -149,9 +149,8 @@ static void dyn_string(STRING_OP op) {
|
|||||||
gen_releasereg(DREG(CYCLES));
|
gen_releasereg(DREG(CYCLES));
|
||||||
dyn_savestate(&cycle_state);
|
dyn_savestate(&cycle_state);
|
||||||
Bit8u * cycle_branch=gen_create_branch(BR_NLE);
|
Bit8u * cycle_branch=gen_create_branch(BR_NLE);
|
||||||
gen_lea(DREG(EIP),DREG(EIP),0,0,decode.op_start-decode.code_start);
|
gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(EIP),decode.op_start-decode.code_start);
|
||||||
dyn_releaseregs();
|
dyn_save_critical_regs();
|
||||||
gen_restoreflags(true);
|
|
||||||
gen_return(BR_Cycles);
|
gen_return(BR_Cycles);
|
||||||
gen_fill_branch(cycle_branch);
|
gen_fill_branch(cycle_branch);
|
||||||
dyn_loadstate(&cycle_state);
|
dyn_loadstate(&cycle_state);
|
||||||
@ -161,5 +160,4 @@ static void dyn_string(STRING_OP op) {
|
|||||||
gen_fill_jump(rep_ecx_jmp);
|
gen_fill_jump(rep_ecx_jmp);
|
||||||
}
|
}
|
||||||
gen_releasereg(DREG(TMPW));
|
gen_releasereg(DREG(TMPW));
|
||||||
gen_restoreflags();
|
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
@ -54,47 +54,28 @@ typedef PhysPt EAPoint;
|
|||||||
#include "core_full/optable.h"
|
#include "core_full/optable.h"
|
||||||
#include "instructions.h"
|
#include "instructions.h"
|
||||||
|
|
||||||
#define LEAVECORE \
|
|
||||||
SaveIP(); \
|
|
||||||
FillFlags();
|
|
||||||
|
|
||||||
#define EXCEPTION(blah) \
|
#define EXCEPTION(blah) \
|
||||||
{ \
|
{ \
|
||||||
Bit8u new_num=blah; \
|
Bit8u new_num=blah; \
|
||||||
IPPoint=inst.opcode_start; \
|
|
||||||
LEAVECORE; \
|
|
||||||
CPU_Exception(new_num,0); \
|
CPU_Exception(new_num,0); \
|
||||||
LoadIP(); \
|
continue; \
|
||||||
goto nextopcode; \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Bits CPU_Core_Full_Run(void) {
|
Bits CPU_Core_Full_Run(void) {
|
||||||
FullData inst;
|
FullData inst;
|
||||||
restart_core:
|
|
||||||
if (!cpu.code.big) {
|
|
||||||
inst.start_prefix=0x0;;
|
|
||||||
inst.start_entry=0x0;
|
|
||||||
} else {
|
|
||||||
inst.start_prefix=PREFIX_ADDR;
|
|
||||||
inst.start_entry=0x200;
|
|
||||||
}
|
|
||||||
EAPoint IPPoint;
|
|
||||||
LoadIP();
|
|
||||||
lflags.type=t_UNKNOWN;
|
|
||||||
while (CPU_Cycles-->0) {
|
while (CPU_Cycles-->0) {
|
||||||
#if C_DEBUG
|
#if C_DEBUG
|
||||||
cycle_count++;
|
cycle_count++;
|
||||||
#if C_HEAVY_DEBUG
|
#if C_HEAVY_DEBUG
|
||||||
SaveIP();
|
|
||||||
if (DEBUG_HeavyIsBreakpoint()) {
|
if (DEBUG_HeavyIsBreakpoint()) {
|
||||||
LEAVECORE;
|
FillFlags();
|
||||||
return debugCallback;
|
return debugCallback;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
inst.opcode_start=IPPoint;
|
LoadIP();
|
||||||
inst.entry=inst.start_entry;
|
inst.entry=cpu.code.big*0x200;
|
||||||
inst.prefix=inst.start_prefix;
|
inst.prefix=cpu.code.big;
|
||||||
restartopcode:
|
restartopcode:
|
||||||
inst.entry=(inst.entry & 0xffffff00) | Fetchb();
|
inst.entry=(inst.entry & 0xffffff00) | Fetchb();
|
||||||
inst.code=OpCodeTable[inst.entry];
|
inst.code=OpCodeTable[inst.entry];
|
||||||
@ -102,9 +83,13 @@ restartopcode:
|
|||||||
#include "core_full/op.h"
|
#include "core_full/op.h"
|
||||||
#include "core_full/save.h"
|
#include "core_full/save.h"
|
||||||
nextopcode:;
|
nextopcode:;
|
||||||
|
SaveIP();
|
||||||
|
continue;
|
||||||
|
illegalopcode:
|
||||||
|
LOG_MSG("Illegal opcode");
|
||||||
|
CPU_Exception(0x6,0);
|
||||||
}
|
}
|
||||||
exit_core:
|
FillFlags();
|
||||||
LEAVECORE;
|
|
||||||
return CBRET_NONE;
|
return CBRET_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,18 +144,12 @@ l_M_Ed:
|
|||||||
inst.op1.d=SegValue((SegNames)inst.rm_index);
|
inst.op1.d=SegValue((SegNames)inst.rm_index);
|
||||||
break;
|
break;
|
||||||
case M_Efw:
|
case M_Efw:
|
||||||
if (inst.rm>=0xC0) {
|
if (inst.rm>=0xc0) goto illegalopcode;
|
||||||
LOG(LOG_CPU,LOG_ERROR)("MODRM:Illegal M_Efw ");
|
|
||||||
goto nextopcode;
|
|
||||||
}
|
|
||||||
inst.op1.d=LoadMw(inst.rm_eaa);
|
inst.op1.d=LoadMw(inst.rm_eaa);
|
||||||
inst.op2.d=LoadMw(inst.rm_eaa+2);
|
inst.op2.d=LoadMw(inst.rm_eaa+2);
|
||||||
break;
|
break;
|
||||||
case M_Efd:
|
case M_Efd:
|
||||||
if (inst.rm>=0xc0) {
|
if (inst.rm>=0xc0) goto illegalopcode;
|
||||||
LOG(LOG_CPU,LOG_ERROR)("MODRM:Illegal M_Efw ");
|
|
||||||
goto nextopcode;
|
|
||||||
}
|
|
||||||
inst.op1.d=LoadMd(inst.rm_eaa);
|
inst.op1.d=LoadMd(inst.rm_eaa);
|
||||||
inst.op2.d=LoadMw(inst.rm_eaa+4);
|
inst.op2.d=LoadMw(inst.rm_eaa+4);
|
||||||
break;
|
break;
|
||||||
@ -183,8 +177,6 @@ l_M_Ed:
|
|||||||
inst.op2.d=1;
|
inst.op2.d=1;
|
||||||
inst.code=Groups[inst.code.op][inst.rm_index];
|
inst.code=Groups[inst.code.op][inst.rm_index];
|
||||||
goto l_MODRMswitch;
|
goto l_MODRMswitch;
|
||||||
|
|
||||||
/* Should continue with normal handler afterwards */
|
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -246,9 +238,6 @@ l_M_Ed:
|
|||||||
case L_REGd:
|
case L_REGd:
|
||||||
inst.op1.d=reg_32(inst.code.extra);
|
inst.op1.d=reg_32(inst.code.extra);
|
||||||
break;
|
break;
|
||||||
case L_FLG:
|
|
||||||
inst.op1.d = FillFlags();
|
|
||||||
break;
|
|
||||||
case L_SEG:
|
case L_SEG:
|
||||||
inst.op1.d=SegValue((SegNames)inst.code.extra);
|
inst.op1.d=SegValue((SegNames)inst.code.extra);
|
||||||
break;
|
break;
|
||||||
@ -282,10 +271,10 @@ l_M_Ed:
|
|||||||
inst.repz=true;
|
inst.repz=true;
|
||||||
goto restartopcode;
|
goto restartopcode;
|
||||||
case L_PREOP:
|
case L_PREOP:
|
||||||
inst.entry=inst.start_entry ^ 0x200;
|
inst.entry=(cpu.code.big ^1) * 0x200;
|
||||||
goto restartopcode;
|
goto restartopcode;
|
||||||
case L_PREADD:
|
case L_PREADD:
|
||||||
inst.prefix^=PREFIX_ADDR;
|
inst.prefix=(inst.prefix & ~1) | (cpu.code.big ^ 1);
|
||||||
goto restartopcode;
|
goto restartopcode;
|
||||||
case L_VAL:
|
case L_VAL:
|
||||||
inst.op1.d=inst.code.extra;
|
inst.op1.d=inst.code.extra;
|
||||||
@ -295,41 +284,40 @@ l_M_Ed:
|
|||||||
inst.op1.d=4;
|
inst.op1.d=4;
|
||||||
break;
|
break;
|
||||||
case D_IRETw:
|
case D_IRETw:
|
||||||
LEAVECORE;
|
FillFlags();
|
||||||
CPU_IRET(false);
|
CPU_IRET(false,GetIP());
|
||||||
if (GETFLAG(IF) && PIC_IRQCheck) {
|
if (GETFLAG(IF) && PIC_IRQCheck) {
|
||||||
return CBRET_NONE;
|
return CBRET_NONE;
|
||||||
}
|
}
|
||||||
goto restart_core;
|
continue;
|
||||||
case D_IRETd:
|
case D_IRETd:
|
||||||
LEAVECORE;
|
FillFlags();
|
||||||
CPU_IRET(true);
|
CPU_IRET(true,GetIP());
|
||||||
if (GETFLAG(IF) && PIC_IRQCheck) {
|
if (GETFLAG(IF) && PIC_IRQCheck)
|
||||||
return CBRET_NONE;
|
return CBRET_NONE;
|
||||||
}
|
continue;
|
||||||
goto restart_core;
|
|
||||||
case D_RETFwIw:
|
case D_RETFwIw:
|
||||||
{
|
{
|
||||||
Bitu words=Fetchw();
|
Bitu words=Fetchw();
|
||||||
LEAVECORE;
|
FillFlags();
|
||||||
CPU_RET(false,words);
|
CPU_RET(false,words,GetIP());
|
||||||
goto restart_core;
|
continue;
|
||||||
}
|
}
|
||||||
case D_RETFw:
|
case D_RETFw:
|
||||||
LEAVECORE;
|
FillFlags();
|
||||||
CPU_RET(false,0);
|
CPU_RET(false,0,GetIP());
|
||||||
goto restart_core;
|
continue;
|
||||||
case D_RETFdIw:
|
case D_RETFdIw:
|
||||||
{
|
{
|
||||||
Bitu words=Fetchw();
|
Bitu words=Fetchw();
|
||||||
LEAVECORE;
|
FillFlags();
|
||||||
CPU_RET(true,words);
|
CPU_RET(true,words,GetIP());
|
||||||
goto restart_core;
|
continue;
|
||||||
}
|
}
|
||||||
case D_RETFd:
|
case D_RETFd:
|
||||||
LEAVECORE;
|
FillFlags();
|
||||||
CPU_RET(true,0);
|
CPU_RET(true,0,GetIP());
|
||||||
goto restart_core;
|
continue;
|
||||||
/* Direct operations */
|
/* Direct operations */
|
||||||
case L_STRING:
|
case L_STRING:
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
@ -357,18 +345,10 @@ l_M_Ed:
|
|||||||
reg_ebx=Pop_32();reg_edx=Pop_32();reg_ecx=Pop_32();reg_eax=Pop_32();
|
reg_ebx=Pop_32();reg_edx=Pop_32();reg_ecx=Pop_32();reg_eax=Pop_32();
|
||||||
goto nextopcode;
|
goto nextopcode;
|
||||||
case D_POPSEGw:
|
case D_POPSEGw:
|
||||||
if (CPU_SetSegGeneral((SegNames)inst.code.extra,Pop_16())) {
|
if (CPU_PopSeg((SegNames)inst.code.extra,false)) RunException();
|
||||||
LEAVECORE;
|
|
||||||
reg_eip-=(IPPoint-inst.opcode_start);reg_esp-=2;
|
|
||||||
CPU_StartException();goto restart_core;
|
|
||||||
}
|
|
||||||
goto nextopcode;
|
goto nextopcode;
|
||||||
case D_POPSEGd:
|
case D_POPSEGd:
|
||||||
if (CPU_SetSegGeneral((SegNames)inst.code.extra,Pop_32())) {
|
if (CPU_PopSeg((SegNames)inst.code.extra,true)) RunException();
|
||||||
LEAVECORE;
|
|
||||||
reg_eip-=(IPPoint-inst.opcode_start);reg_esp-=4;
|
|
||||||
CPU_StartException();goto restart_core;
|
|
||||||
}
|
|
||||||
goto nextopcode;
|
goto nextopcode;
|
||||||
case D_SETALC:
|
case D_SETALC:
|
||||||
reg_al = get_CF() ? 0xFF : 0;
|
reg_al = get_CF() ? 0xFF : 0;
|
||||||
@ -403,14 +383,10 @@ l_M_Ed:
|
|||||||
else reg_edx=0;
|
else reg_edx=0;
|
||||||
goto nextopcode;
|
goto nextopcode;
|
||||||
case D_CLI:
|
case D_CLI:
|
||||||
SETFLAGBIT(IF,false);
|
if (CPU_CLI()) RunException();
|
||||||
goto nextopcode;
|
goto nextopcode;
|
||||||
case D_STI:
|
case D_STI:
|
||||||
SETFLAGBIT(IF,true);
|
if (CPU_STI()) RunException();
|
||||||
if (GETFLAG(IF) && PIC_IRQCheck) {
|
|
||||||
LEAVECORE;
|
|
||||||
return CBRET_NONE;
|
|
||||||
}
|
|
||||||
goto nextopcode;
|
goto nextopcode;
|
||||||
case D_STC:
|
case D_STC:
|
||||||
FillFlags();SETFLAGBIT(CF,true);
|
FillFlags();SETFLAGBIT(CF,true);
|
||||||
@ -430,71 +406,40 @@ l_M_Ed:
|
|||||||
SETFLAGBIT(DF,true);
|
SETFLAGBIT(DF,true);
|
||||||
cpu.direction=-1;
|
cpu.direction=-1;
|
||||||
goto nextopcode;
|
goto nextopcode;
|
||||||
|
case D_PUSHF:
|
||||||
|
FillFlags();
|
||||||
|
if (CPU_PUSHF(inst.code.extra)) RunException();
|
||||||
|
goto nextopcode;
|
||||||
|
case D_POPF:
|
||||||
|
if (CPU_POPF(inst.code.extra)) RunException();
|
||||||
|
lflags.type=t_UNKNOWN;
|
||||||
|
if (GETFLAG(IF) && PIC_IRQCheck) {
|
||||||
|
SaveIP();
|
||||||
|
return CBRET_NONE;
|
||||||
|
}
|
||||||
|
goto nextopcode;
|
||||||
|
case D_SAHF:
|
||||||
|
SETFLAGSb(reg_ah);
|
||||||
|
goto nextopcode;
|
||||||
|
case D_LAHF:
|
||||||
|
FillFlags();
|
||||||
|
reg_ah=reg_flags&0xff;
|
||||||
|
goto nextopcode;
|
||||||
case D_WAIT:
|
case D_WAIT:
|
||||||
case D_NOP:
|
case D_NOP:
|
||||||
goto nextopcode;
|
goto nextopcode;
|
||||||
case D_ENTERw:
|
case D_ENTERw:
|
||||||
{
|
{
|
||||||
Bitu bytes=Fetchw();Bitu level=Fetchb() & 0x1f;
|
Bitu bytes=Fetchw();
|
||||||
Bitu frame_ptr=reg_esp-2;
|
Bitu level=Fetchb();
|
||||||
if (cpu.stack.big) {
|
CPU_ENTER(false,bytes,level);
|
||||||
reg_esp-=2;
|
|
||||||
mem_writew(SegBase(ss)+reg_esp,reg_bp);
|
|
||||||
for (Bitu i=1;i<level;i++) {
|
|
||||||
reg_ebp-=2;reg_esp-=2;
|
|
||||||
mem_writew(SegBase(ss)+reg_esp,mem_readw(SegBase(ss)+reg_ebp));
|
|
||||||
}
|
|
||||||
if (level) {
|
|
||||||
reg_esp-=2;
|
|
||||||
mem_writew(SegBase(ss)+reg_esp,(Bit16u)frame_ptr);
|
|
||||||
}
|
|
||||||
reg_esp-=bytes;
|
|
||||||
} else {
|
|
||||||
reg_sp-=2;
|
|
||||||
mem_writew(SegBase(ss)+reg_sp,reg_bp);
|
|
||||||
for (Bitu i=1;i<level;i++) {
|
|
||||||
reg_bp-=2;reg_sp-=2;
|
|
||||||
mem_writew(SegBase(ss)+reg_sp,mem_readw(SegBase(ss)+reg_bp));
|
|
||||||
}
|
|
||||||
if (level) {
|
|
||||||
reg_sp-=2;
|
|
||||||
mem_writew(SegBase(ss)+reg_sp,(Bit16u)frame_ptr);
|
|
||||||
}
|
|
||||||
reg_sp-=bytes;
|
|
||||||
}
|
|
||||||
reg_bp=frame_ptr;
|
|
||||||
goto nextopcode;
|
goto nextopcode;
|
||||||
}
|
}
|
||||||
case D_ENTERd:
|
case D_ENTERd:
|
||||||
{
|
{
|
||||||
Bitu bytes=Fetchw();Bitu level=Fetchb() & 0x1f;
|
Bitu bytes=Fetchw();
|
||||||
Bitu frame_ptr=reg_esp-4;
|
Bitu level=Fetchb();
|
||||||
if (cpu.stack.big) {
|
CPU_ENTER(true,bytes,level);
|
||||||
reg_esp-=4;
|
|
||||||
mem_writed(SegBase(ss)+reg_esp,reg_ebp);
|
|
||||||
for (Bitu i=1;i<level;i++) {
|
|
||||||
reg_ebp-=4;reg_esp-=4;
|
|
||||||
mem_writed(SegBase(ss)+reg_esp,mem_readd(SegBase(ss)+reg_ebp));
|
|
||||||
}
|
|
||||||
if (level) {
|
|
||||||
reg_esp-=4;
|
|
||||||
mem_writed(SegBase(ss)+reg_esp,(Bit32u)frame_ptr);
|
|
||||||
}
|
|
||||||
reg_esp-=bytes;
|
|
||||||
} else {
|
|
||||||
reg_sp-=4;
|
|
||||||
mem_writed(SegBase(ss)+reg_sp,reg_ebp);
|
|
||||||
for (Bitu i=1;i<level;i++) {
|
|
||||||
reg_bp-=4;reg_sp-=4;
|
|
||||||
mem_writed(SegBase(ss)+reg_sp,mem_readd(SegBase(ss)+reg_bp));
|
|
||||||
}
|
|
||||||
if (level) {
|
|
||||||
reg_sp-=4;
|
|
||||||
mem_writed(SegBase(ss)+reg_sp,(Bit32u)frame_ptr);
|
|
||||||
}
|
|
||||||
reg_sp-=bytes;
|
|
||||||
}
|
|
||||||
reg_ebp=frame_ptr;
|
|
||||||
goto nextopcode;
|
goto nextopcode;
|
||||||
}
|
}
|
||||||
case D_LEAVEw:
|
case D_LEAVEw:
|
||||||
@ -523,14 +468,14 @@ l_M_Ed:
|
|||||||
CPU_CPUID();
|
CPU_CPUID();
|
||||||
goto nextopcode;
|
goto nextopcode;
|
||||||
case D_HLT:
|
case D_HLT:
|
||||||
LEAVECORE;
|
FillFlags();
|
||||||
CPU_HLT(IPPoint-inst.opcode_start);
|
CPU_HLT(GetIP());
|
||||||
return CBRET_NONE;
|
return CBRET_NONE;
|
||||||
case D_CLTS:
|
case D_CLTS:
|
||||||
//TODO Really clear it sometime
|
//TODO Really clear it sometime
|
||||||
goto nextopcode;
|
goto nextopcode;
|
||||||
default:
|
default:
|
||||||
LOG(LOG_CPU,LOG_ERROR)("LOAD:Unhandled code %d opcode %X",inst.code.load,inst.entry);
|
LOG(LOG_CPU,LOG_ERROR)("LOAD:Unhandled code %d opcode %X",inst.code.load,inst.entry);
|
||||||
break;
|
goto illegalopcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
#define SaveIP() reg_eip=(Bit32u)(IPPoint-SegBase(cs));
|
#define SaveIP() reg_eip=(Bit32u)(inst.cseip-SegBase(cs));
|
||||||
#define LoadIP() IPPoint=SegBase(cs)+reg_eip;
|
#define LoadIP() inst.cseip=SegBase(cs)+reg_eip;
|
||||||
|
#define GetIP() (inst.cseip-SegBase(cs))
|
||||||
|
|
||||||
|
#define RunException() { \
|
||||||
|
FillFlags(); \
|
||||||
|
CPU_Exception(cpu.exception.which,cpu.exception.error); \
|
||||||
|
continue; \
|
||||||
|
}
|
||||||
|
|
||||||
static INLINE Bit8u the_Fetchb(EAPoint & loc) {
|
static INLINE Bit8u the_Fetchb(EAPoint & loc) {
|
||||||
Bit8u temp=LoadMb(loc);
|
Bit8u temp=LoadMb(loc);
|
||||||
@ -19,42 +25,16 @@ static INLINE Bit32u the_Fetchd(EAPoint & loc) {
|
|||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define Fetchb() the_Fetchb(IPPoint)
|
#define Fetchb() the_Fetchb(inst.cseip)
|
||||||
#define Fetchw() the_Fetchw(IPPoint)
|
#define Fetchw() the_Fetchw(inst.cseip)
|
||||||
#define Fetchd() the_Fetchd(IPPoint)
|
#define Fetchd() the_Fetchd(inst.cseip)
|
||||||
|
|
||||||
#define Fetchbs() (Bit8s)the_Fetchb(IPPoint)
|
#define Fetchbs() (Bit8s)the_Fetchb(inst.cseip)
|
||||||
#define Fetchws() (Bit16s)the_Fetchw(IPPoint)
|
#define Fetchws() (Bit16s)the_Fetchw(inst.cseip)
|
||||||
#define Fetchds() (Bit32s)the_Fetchd(IPPoint)
|
#define Fetchds() (Bit32s)the_Fetchd(inst.cseip)
|
||||||
|
|
||||||
#if 0
|
|
||||||
static INLINE void Push_16(Bit16u blah) {
|
|
||||||
reg_esp-=2;
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE Bit16u Pop_16(void) {
|
|
||||||
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));
|
|
||||||
reg_esp+=4;
|
|
||||||
return temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define Push_16 CPU_Push16
|
#define Push_16 CPU_Push16
|
||||||
#define Push_32 CPU_Push32
|
#define Push_32 CPU_Push32
|
||||||
#define Pop_16 CPU_Pop16
|
#define Pop_16 CPU_Pop16
|
||||||
#define Pop_32 CPU_Pop32
|
#define Pop_32 CPU_Pop32
|
||||||
|
|
||||||
#endif
|
|
||||||
|
@ -322,51 +322,57 @@ switch (inst.code.op) {
|
|||||||
Push_32(reg_eip);
|
Push_32(reg_eip);
|
||||||
break;
|
break;
|
||||||
case O_CALLFw:
|
case O_CALLFw:
|
||||||
LEAVECORE;
|
FillFlags();
|
||||||
CPU_CALL(false,inst.op2.d,inst.op1.d);
|
CPU_CALL(false,inst.op2.d,inst.op1.d,GetIP());
|
||||||
goto restart_core;
|
continue;
|
||||||
case O_CALLFd:
|
case O_CALLFd:
|
||||||
LEAVECORE;
|
FillFlags();
|
||||||
CPU_CALL(true,inst.op2.d,inst.op1.d);
|
CPU_CALL(true,inst.op2.d,inst.op1.d,GetIP());
|
||||||
goto restart_core;
|
continue;
|
||||||
case O_JMPFw:
|
case O_JMPFw:
|
||||||
LEAVECORE;
|
FillFlags();
|
||||||
CPU_JMP(false,inst.op2.d,inst.op1.d);
|
CPU_JMP(false,inst.op2.d,inst.op1.d,GetIP());
|
||||||
goto restart_core;
|
continue;
|
||||||
case O_JMPFd:
|
case O_JMPFd:
|
||||||
LEAVECORE;
|
FillFlags();
|
||||||
CPU_JMP(true,inst.op2.d,inst.op1.d);
|
CPU_JMP(true,inst.op2.d,inst.op1.d,GetIP());
|
||||||
goto restart_core;
|
continue;
|
||||||
case O_INT:
|
case O_INT:
|
||||||
LEAVECORE;
|
FillFlags();
|
||||||
#if C_DEBUG
|
#if C_DEBUG
|
||||||
if (((inst.entry & 0xFF)==0xcc) && DEBUG_Breakpoint())
|
if (((inst.entry & 0xFF)==0xcc) && DEBUG_Breakpoint())
|
||||||
return debugCallback;
|
return debugCallback;
|
||||||
else if (DEBUG_IntBreakpoint(inst.op1.b))
|
else if (DEBUG_IntBreakpoint(inst.op1.b))
|
||||||
return debugCallback;
|
return debugCallback;
|
||||||
#endif
|
#endif
|
||||||
CPU_SW_Interrupt(inst.op1.b,IPPoint-inst.opcode_start);
|
CPU_SW_Interrupt(inst.op1.b,GetIP());
|
||||||
goto restart_core;
|
continue;
|
||||||
case O_INb:
|
case O_INb:
|
||||||
|
if (CPU_IO_Exception(inst.op1.d,1)) RunException();
|
||||||
reg_al=IO_ReadB(inst.op1.d);
|
reg_al=IO_ReadB(inst.op1.d);
|
||||||
goto nextopcode;
|
goto nextopcode;
|
||||||
case O_INw:
|
case O_INw:
|
||||||
|
if (CPU_IO_Exception(inst.op1.d,2)) RunException();
|
||||||
reg_ax=IO_ReadW(inst.op1.d);
|
reg_ax=IO_ReadW(inst.op1.d);
|
||||||
goto nextopcode;
|
goto nextopcode;
|
||||||
case O_INd:
|
case O_INd:
|
||||||
|
if (CPU_IO_Exception(inst.op1.d,4)) RunException();
|
||||||
reg_eax=IO_ReadD(inst.op1.d);
|
reg_eax=IO_ReadD(inst.op1.d);
|
||||||
goto nextopcode;
|
goto nextopcode;
|
||||||
case O_OUTb:
|
case O_OUTb:
|
||||||
|
if (CPU_IO_Exception(inst.op1.d,1)) RunException();
|
||||||
IO_WriteB(inst.op1.d,reg_al);
|
IO_WriteB(inst.op1.d,reg_al);
|
||||||
goto nextopcode;
|
goto nextopcode;
|
||||||
case O_OUTw:
|
case O_OUTw:
|
||||||
|
if (CPU_IO_Exception(inst.op1.d,2)) RunException();
|
||||||
IO_WriteW(inst.op1.d,reg_ax);
|
IO_WriteW(inst.op1.d,reg_ax);
|
||||||
goto nextopcode;
|
goto nextopcode;
|
||||||
case O_OUTd:
|
case O_OUTd:
|
||||||
|
if (CPU_IO_Exception(inst.op1.d,4)) RunException();
|
||||||
IO_WriteD(inst.op1.d,reg_eax);
|
IO_WriteD(inst.op1.d,reg_eax);
|
||||||
goto nextopcode;
|
goto nextopcode;
|
||||||
case O_CBACK:
|
case O_CBACK:
|
||||||
LEAVECORE;
|
FillFlags();SaveIP();
|
||||||
return inst.op1.d;
|
return inst.op1.d;
|
||||||
case O_GRP6w:
|
case O_GRP6w:
|
||||||
case O_GRP6d:
|
case O_GRP6d:
|
||||||
@ -458,19 +464,22 @@ switch (inst.code.op) {
|
|||||||
case O_LAR:
|
case O_LAR:
|
||||||
{
|
{
|
||||||
FillFlags();
|
FillFlags();
|
||||||
Bitu ar;CPU_LAR(inst.op1.d,ar);
|
Bitu ar=inst.op2.d;
|
||||||
|
CPU_LAR(inst.op1.w,ar);
|
||||||
inst.op1.d=(Bit32u)ar;
|
inst.op1.d=(Bit32u)ar;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case O_LSL:
|
case O_LSL:
|
||||||
{
|
{
|
||||||
FillFlags();
|
FillFlags();
|
||||||
Bitu limit;CPU_LSL(inst.op1.d,limit);
|
Bitu limit=inst.op2.d;
|
||||||
|
CPU_LSL(inst.op1.w,limit);
|
||||||
inst.op1.d=(Bit32u)limit;
|
inst.op1.d=(Bit32u)limit;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case O_ARPL:
|
case O_ARPL:
|
||||||
{
|
{
|
||||||
|
if ((reg_flags & FLAG_VM) || !cpu.pmode) goto illegalopcode;
|
||||||
FillFlags();
|
FillFlags();
|
||||||
Bitu new_sel=inst.op1.d;
|
Bitu new_sel=inst.op1.d;
|
||||||
CPU_ARPL(new_sel,inst.op2.d);
|
CPU_ARPL(new_sel,inst.op2.d);
|
||||||
|
@ -110,8 +110,9 @@ static OpCode OpCodeTable[1024]={
|
|||||||
/* 0x98 - 0x9f */
|
/* 0x98 - 0x9f */
|
||||||
{D_CBW ,0 ,0 ,0 },{D_CWD ,0 ,0 ,0 },
|
{D_CBW ,0 ,0 ,0 },{D_CWD ,0 ,0 ,0 },
|
||||||
{L_Ifw ,O_CALLFw ,0 ,0 },{D_WAIT ,0 ,0 ,0 },
|
{L_Ifw ,O_CALLFw ,0 ,0 },{D_WAIT ,0 ,0 ,0 },
|
||||||
{L_FLG ,0 ,S_PUSHw,0 },{L_POPw ,0 ,S_FLGw ,0 },
|
{D_PUSHF ,0 ,0 ,0 },{D_POPF ,0 ,0 ,0 },
|
||||||
{L_REGb ,0 ,S_FLGb ,REGI_AH},{L_FLG ,0 ,S_REGb ,REGI_AH},
|
{D_SAHF ,0 ,0 ,0 },{D_LAHF ,0 ,0 ,0 },
|
||||||
|
|
||||||
|
|
||||||
/* 0xa0 - 0xa7 */
|
/* 0xa0 - 0xa7 */
|
||||||
{L_OP ,O_ALOP ,0 ,0 },{L_OP ,O_AXOP ,0 ,0 },
|
{L_OP ,O_ALOP ,0 ,0 },{L_OP ,O_AXOP ,0 ,0 },
|
||||||
@ -182,7 +183,7 @@ static OpCode OpCodeTable[1024]={
|
|||||||
|
|
||||||
/* 0x100 - 0x107 */
|
/* 0x100 - 0x107 */
|
||||||
{L_MODRM ,O_GRP6w ,S_Ew ,M_Ew },{L_MODRM ,O_GRP7w ,S_Ew ,M_Ew },
|
{L_MODRM ,O_GRP6w ,S_Ew ,M_Ew },{L_MODRM ,O_GRP7w ,S_Ew ,M_Ew },
|
||||||
{L_MODRM ,O_LAR ,S_Gw ,M_Ew },{L_MODRM ,O_LSL ,S_Gw ,M_Ew },
|
{L_MODRM ,O_LAR ,S_Gw ,M_EwGw },{L_MODRM ,O_LSL ,S_Gw ,M_EwGw },
|
||||||
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
|
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
|
||||||
{D_CLTS ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
|
{D_CLTS ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
|
||||||
/* 0x108 - 0x10f */
|
/* 0x108 - 0x10f */
|
||||||
@ -466,8 +467,8 @@ static OpCode OpCodeTable[1024]={
|
|||||||
/* 0x298 - 0x29f */
|
/* 0x298 - 0x29f */
|
||||||
{D_CWDE ,0 ,0 ,0 },{D_CDQ ,0 ,0 ,0 },
|
{D_CWDE ,0 ,0 ,0 },{D_CDQ ,0 ,0 ,0 },
|
||||||
{L_Ifd ,O_CALLFd ,0 ,0 },{D_WAIT ,0 ,0 ,0 },
|
{L_Ifd ,O_CALLFd ,0 ,0 },{D_WAIT ,0 ,0 ,0 },
|
||||||
{L_FLG ,0 ,S_PUSHd,0 },{L_POPd ,0 ,S_FLGd ,0 },
|
{D_PUSHF ,0 ,0 ,true },{D_POPF ,0 ,0 ,true },
|
||||||
{L_REGb ,0 ,S_FLGb ,REGI_AH},{L_FLG ,0 ,S_REGb ,REGI_AH},
|
{D_SAHF ,0 ,0 ,0 },{D_LAHF ,0 ,0 ,0 },
|
||||||
|
|
||||||
/* 0x2a0 - 0x2a7 */
|
/* 0x2a0 - 0x2a7 */
|
||||||
{L_OP ,O_ALOP ,0 ,0 },{L_OP ,O_EAXOP ,0 ,0 },
|
{L_OP ,O_ALOP ,0 ,0 },{L_OP ,O_EAXOP ,0 ,0 },
|
||||||
@ -538,7 +539,7 @@ static OpCode OpCodeTable[1024]={
|
|||||||
|
|
||||||
/* 0x300 - 0x307 */
|
/* 0x300 - 0x307 */
|
||||||
{L_MODRM ,O_GRP6d ,S_Ew ,M_Ew },{L_MODRM ,O_GRP7d ,S_Ew ,M_Ew },
|
{L_MODRM ,O_GRP6d ,S_Ew ,M_Ew },{L_MODRM ,O_GRP7d ,S_Ew ,M_Ew },
|
||||||
{L_MODRM ,O_LAR ,S_Gd ,M_Ew },{L_MODRM ,O_LSL ,S_Gd ,M_Ew },
|
{L_MODRM ,O_LAR ,S_Gd ,M_EdGd },{L_MODRM ,O_LSL ,S_Gd ,M_EdGd },
|
||||||
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
|
{0 ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
|
||||||
{D_CLTS ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
|
{D_CLTS ,0 ,0 ,0 },{0 ,0 ,0 ,0 },
|
||||||
/* 0x308 - 0x30f */
|
/* 0x308 - 0x30f */
|
||||||
|
@ -56,29 +56,14 @@ switch (inst.code.save) {
|
|||||||
reg_32(inst.code.extra)=inst.op1.d;
|
reg_32(inst.code.extra)=inst.op1.d;
|
||||||
break;
|
break;
|
||||||
case S_SEGm:
|
case S_SEGm:
|
||||||
if (CPU_SetSegGeneral((SegNames)inst.rm_index,inst.op1.w)) {
|
if (CPU_SetSegGeneral((SegNames)inst.rm_index,inst.op1.w)) RunException();
|
||||||
LEAVECORE;
|
|
||||||
reg_eip-=(IPPoint-inst.opcode_start);
|
|
||||||
CPU_StartException();
|
|
||||||
goto restart_core;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case S_SEGGw:
|
case S_SEGGw:
|
||||||
if (CPU_SetSegGeneral((SegNames)inst.code.extra,inst.op2.w)) {
|
if (CPU_SetSegGeneral((SegNames)inst.code.extra,inst.op2.w)) RunException();
|
||||||
LEAVECORE;
|
|
||||||
reg_eip-=(IPPoint-inst.opcode_start);
|
|
||||||
CPU_StartException();
|
|
||||||
goto restart_core;
|
|
||||||
}
|
|
||||||
reg_16(inst.rm_index)=inst.op1.w;
|
reg_16(inst.rm_index)=inst.op1.w;
|
||||||
break;
|
break;
|
||||||
case S_SEGGd:
|
case S_SEGGd:
|
||||||
if (CPU_SetSegGeneral((SegNames)inst.code.extra,inst.op2.w)) {
|
if (CPU_SetSegGeneral((SegNames)inst.code.extra,inst.op2.w)) RunException();
|
||||||
LEAVECORE;
|
|
||||||
reg_eip-=(IPPoint-inst.opcode_start);
|
|
||||||
CPU_StartException();
|
|
||||||
goto restart_core;
|
|
||||||
}
|
|
||||||
reg_32(inst.rm_index)=inst.op1.d;
|
reg_32(inst.rm_index)=inst.op1.d;
|
||||||
break;
|
break;
|
||||||
case S_PUSHw:
|
case S_PUSHw:
|
||||||
@ -94,39 +79,19 @@ switch (inst.code.save) {
|
|||||||
SaveIP();
|
SaveIP();
|
||||||
reg_eip+=inst.op1.d;
|
reg_eip+=inst.op1.d;
|
||||||
reg_eip&=0xffff;
|
reg_eip&=0xffff;
|
||||||
LoadIP();
|
continue;
|
||||||
break;
|
|
||||||
case S_C_AIPd:
|
case S_C_AIPd:
|
||||||
if (!inst.cond) goto nextopcode;
|
if (!inst.cond) goto nextopcode;
|
||||||
case S_AIPd:
|
case S_AIPd:
|
||||||
SaveIP();
|
SaveIP();
|
||||||
reg_eip+=inst.op1.d;
|
reg_eip+=inst.op1.d;
|
||||||
LoadIP();
|
continue;
|
||||||
break;
|
|
||||||
case S_IPIw:
|
case S_IPIw:
|
||||||
reg_esp+=Fetchw();
|
reg_esp+=Fetchw();
|
||||||
case S_IP:
|
case S_IP:
|
||||||
SaveIP();
|
SaveIP();
|
||||||
reg_eip=inst.op1.d;
|
reg_eip=inst.op1.d;
|
||||||
LoadIP();
|
continue;
|
||||||
break;
|
|
||||||
case S_FLGb:
|
|
||||||
SETFLAGSb(inst.op1.b);
|
|
||||||
break;
|
|
||||||
case S_FLGw:
|
|
||||||
SETFLAGSw(inst.op1.w);
|
|
||||||
if (GETFLAG(IF) && PIC_IRQCheck) {
|
|
||||||
SaveIP();
|
|
||||||
return CBRET_NONE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case S_FLGd:
|
|
||||||
SETFLAGSd(inst.op1.d);
|
|
||||||
if (GETFLAG(IF) && PIC_IRQCheck) {
|
|
||||||
SaveIP();
|
|
||||||
return CBRET_NONE;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 0:
|
case 0:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
count_left=count-CPU_Cycles;
|
count_left=count-CPU_Cycles;
|
||||||
count=CPU_Cycles;
|
count=CPU_Cycles;
|
||||||
CPU_Cycles=0;
|
CPU_Cycles=0;
|
||||||
IPPoint=inst.opcode_start; //Reset IP to start of instruction
|
LoadIP();
|
||||||
} else {
|
} else {
|
||||||
/* Won't interrupt scas and cmps instruction since they can interrupt themselves */
|
/* Won't interrupt scas and cmps instruction since they can interrupt themselves */
|
||||||
count_left=0;
|
count_left=0;
|
||||||
|
@ -15,7 +15,7 @@ enum {
|
|||||||
L_POPfw,L_POPfd,
|
L_POPfw,L_POPfd,
|
||||||
L_SEG,
|
L_SEG,
|
||||||
|
|
||||||
L_FLG,L_INTO,
|
L_INTO,
|
||||||
|
|
||||||
L_VAL,
|
L_VAL,
|
||||||
L_PRESEG,
|
L_PRESEG,
|
||||||
@ -41,6 +41,8 @@ enum {
|
|||||||
|
|
||||||
D_RETFw,D_RETFd,
|
D_RETFw,D_RETFd,
|
||||||
D_RETFwIw,D_RETFdIw,
|
D_RETFwIw,D_RETFdIw,
|
||||||
|
D_POPF,D_PUSHF,
|
||||||
|
D_SAHF,D_LAHF,
|
||||||
D_CPUID,
|
D_CPUID,
|
||||||
D_HLT,D_CLTS,
|
D_HLT,D_CLTS,
|
||||||
L_ERROR,
|
L_ERROR,
|
||||||
@ -113,7 +115,6 @@ enum {
|
|||||||
S_AIPw,S_C_AIPw,
|
S_AIPw,S_C_AIPw,
|
||||||
S_AIPd,S_C_AIPd,
|
S_AIPd,S_C_AIPd,
|
||||||
|
|
||||||
S_FLGb,S_FLGw,S_FLGd,
|
|
||||||
S_IP,S_IPIw,
|
S_IP,S_IPIw,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -155,7 +156,6 @@ struct OpCode {
|
|||||||
|
|
||||||
struct FullData {
|
struct FullData {
|
||||||
Bitu entry;
|
Bitu entry;
|
||||||
EAPoint opcode_start;
|
|
||||||
Bitu rm;
|
Bitu rm;
|
||||||
EAPoint rm_eaa;
|
EAPoint rm_eaa;
|
||||||
Bitu rm_off;
|
Bitu rm_off;
|
||||||
@ -163,6 +163,7 @@ struct FullData {
|
|||||||
Bitu rm_index;
|
Bitu rm_index;
|
||||||
Bitu rm_mod;
|
Bitu rm_mod;
|
||||||
OpCode code;
|
OpCode code;
|
||||||
|
EAPoint cseip;
|
||||||
union {
|
union {
|
||||||
Bit8u b;Bit8s bs;
|
Bit8u b;Bit8s bs;
|
||||||
Bit16u w;Bit16s ws;
|
Bit16u w;Bit16s ws;
|
||||||
@ -175,13 +176,11 @@ struct FullData {
|
|||||||
Bitu cond;
|
Bitu cond;
|
||||||
bool repz;
|
bool repz;
|
||||||
Bitu prefix;
|
Bitu prefix;
|
||||||
Bitu start_prefix;
|
|
||||||
Bitu start_entry;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#define PREFIX_NONE 0x0
|
#define PREFIX_NONE 0x0
|
||||||
#define PREFIX_SEG 0x1
|
#define PREFIX_ADDR 0x1
|
||||||
#define PREFIX_ADDR 0x2
|
#define PREFIX_SEG 0x2
|
||||||
#define PREFIX_REP 0x4
|
#define PREFIX_REP 0x4
|
||||||
|
|
||||||
|
@ -9,13 +9,14 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "dosbox.h"
|
#include "dosbox.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
@ -30,43 +31,23 @@
|
|||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define SegBase(c) SegPhys(c)
|
|
||||||
#if (!C_CORE_INLINE)
|
#if (!C_CORE_INLINE)
|
||||||
|
|
||||||
#define LoadMb(off) mem_readb(off)
|
#define LoadMb(off) mem_readb(off)
|
||||||
#define LoadMw(off) mem_readw(off)
|
#define LoadMw(off) mem_readw(off)
|
||||||
#define LoadMd(off) mem_readd(off)
|
#define LoadMd(off) mem_readd(off)
|
||||||
|
|
||||||
#define SaveMb(off,val) mem_writeb(off,val)
|
#define SaveMb(off,val) mem_writeb(off,val)
|
||||||
#define SaveMw(off,val) mem_writew(off,val)
|
#define SaveMw(off,val) mem_writew(off,val)
|
||||||
#define SaveMd(off,val) mem_writed(off,val)
|
#define SaveMd(off,val) mem_writed(off,val)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include "paging.h"
|
#include "paging.h"
|
||||||
#define LoadMb(off) mem_readb_inline(off)
|
#define LoadMb(off) mem_readb_inline(off)
|
||||||
#define LoadMw(off) mem_readw_inline(off)
|
#define LoadMw(off) mem_readw_inline(off)
|
||||||
#define LoadMd(off) mem_readd_inline(off)
|
#define LoadMd(off) mem_readd_inline(off)
|
||||||
|
|
||||||
#define SaveMb(off,val) mem_writeb_inline(off,val)
|
#define SaveMb(off,val) mem_writeb_inline(off,val)
|
||||||
#define SaveMw(off,val) mem_writew_inline(off,val)
|
#define SaveMw(off,val) mem_writew_inline(off,val)
|
||||||
#define SaveMd(off,val) mem_writed_inline(off,val)
|
#define SaveMd(off,val) mem_writed_inline(off,val)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define LoadMbs(off) (Bit8s)(LoadMb(off))
|
|
||||||
#define LoadMws(off) (Bit16s)(LoadMw(off))
|
|
||||||
#define LoadMds(off) (Bit32s)(LoadMd(off))
|
|
||||||
|
|
||||||
#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;
|
extern Bitu cycle_count;
|
||||||
|
|
||||||
#if C_FPU
|
#if C_FPU
|
||||||
@ -80,122 +61,129 @@ extern Bitu cycle_count;
|
|||||||
#define OPCODE_0F 0x100
|
#define OPCODE_0F 0x100
|
||||||
#define OPCODE_SIZE 0x200
|
#define OPCODE_SIZE 0x200
|
||||||
|
|
||||||
#define PREFIX_SEG 0x1
|
#define PREFIX_ADDR 0x1
|
||||||
#define PREFIX_ADDR 0x2
|
#define PREFIX_REP 0x2
|
||||||
#define PREFIX_SEG_ADDR (PREFIX_SEG|PREFIX_ADDR)
|
|
||||||
#define PREFIX_REP 0x4
|
|
||||||
|
|
||||||
#define TEST_PREFIX_SEG (core.prefixes & PREFIX_SEG)
|
|
||||||
#define TEST_PREFIX_ADDR (core.prefixes & PREFIX_ADDR)
|
#define TEST_PREFIX_ADDR (core.prefixes & PREFIX_ADDR)
|
||||||
#define TEST_PREFIX_REP (core.prefixes & PREFIX_REP)
|
#define TEST_PREFIX_REP (core.prefixes & PREFIX_REP)
|
||||||
|
|
||||||
#define DO_PREFIX_SEG(_SEG) \
|
#define DO_PREFIX_SEG(_SEG) \
|
||||||
core.prefixes|=PREFIX_SEG; \
|
BaseDS=SegBase(_SEG); \
|
||||||
core.seg_prefix_base=SegBase(_SEG); \
|
BaseSS=SegBase(_SEG); \
|
||||||
goto restart_prefix;
|
goto restart_opcode;
|
||||||
|
|
||||||
#define DO_PREFIX_ADDR() \
|
#define DO_PREFIX_ADDR() \
|
||||||
core.prefixes^=PREFIX_ADDR; \
|
core.prefixes=(core.prefixes & ~PREFIX_ADDR) | \
|
||||||
goto restart_prefix;
|
(cpu.code.big ^ PREFIX_ADDR); \
|
||||||
|
core.ea_table=&EATable[(core.prefixes&1) * 256]; \
|
||||||
|
goto restart_opcode;
|
||||||
|
|
||||||
#define DO_PREFIX_REP(_ZERO) \
|
#define DO_PREFIX_REP(_ZERO) \
|
||||||
core.prefixes|=PREFIX_REP; \
|
core.prefixes|=PREFIX_REP; \
|
||||||
core.rep_zero=_ZERO; \
|
core.rep_zero=_ZERO; \
|
||||||
goto restart_prefix;
|
goto restart_opcode;
|
||||||
|
|
||||||
typedef PhysPt (*GetEATable[256])(void);
|
typedef PhysPt (*GetEAHandler)(void);
|
||||||
|
|
||||||
|
static const Bit32u AddrMaskTable[2]={0x0000ffff,0xffffffff};
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
Bitu opcode_index;
|
Bitu opcode_index;
|
||||||
Bitu prefixes;
|
PhysPt cseip;
|
||||||
Bitu index_default;
|
PhysPt base_ds,base_ss;
|
||||||
Bitu prefix_default;
|
|
||||||
PhysPt op_start;
|
|
||||||
PhysPt ip_lookup;
|
|
||||||
PhysPt seg_prefix_base;
|
|
||||||
bool rep_zero;
|
bool rep_zero;
|
||||||
GetEATable * ea_table;
|
Bitu prefixes;
|
||||||
|
GetEAHandler * ea_table;
|
||||||
struct {
|
struct {
|
||||||
bool skip;
|
bool skip;
|
||||||
} trap;
|
} trap;
|
||||||
} core;
|
} core;
|
||||||
|
|
||||||
|
#define GETIP (core.cseip-SegBase(cs))
|
||||||
|
#define SAVEIP reg_eip=GETIP;
|
||||||
|
#define LOADIP core.cseip=(SegBase(cs)+reg_eip);
|
||||||
|
|
||||||
|
#define SegBase(c) SegPhys(c)
|
||||||
|
#define BaseDS core.base_ds
|
||||||
|
#define BaseSS core.base_ss
|
||||||
|
|
||||||
|
static INLINE Bit8u Fetchb() {
|
||||||
|
Bit8u temp=LoadMb(core.cseip);
|
||||||
|
core.cseip+=1;
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static INLINE Bit16u Fetchw() {
|
||||||
|
Bit16u temp=LoadMw(core.cseip);
|
||||||
|
core.cseip+=2;
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
static INLINE Bit32u Fetchd() {
|
||||||
|
Bit32u temp=LoadMd(core.cseip);
|
||||||
|
core.cseip+=4;
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define Push_16 CPU_Push16
|
||||||
|
#define Push_32 CPU_Push32
|
||||||
|
#define Pop_16 CPU_Pop16
|
||||||
|
#define Pop_32 CPU_Pop32
|
||||||
|
|
||||||
#include "instructions.h"
|
#include "instructions.h"
|
||||||
#include "core_normal/support.h"
|
#include "core_normal/support.h"
|
||||||
#include "core_normal/string.h"
|
#include "core_normal/string.h"
|
||||||
|
|
||||||
static GetEATable * EAPrefixTable[8] = {
|
|
||||||
&GetEA_NONE,&GetEA_SEG,&GetEA_ADDR,&GetEA_SEG_ADDR,
|
|
||||||
&GetEA_NONE,&GetEA_SEG,&GetEA_ADDR,&GetEA_SEG_ADDR,
|
|
||||||
};
|
|
||||||
|
|
||||||
#define CASE_W(_WHICH) \
|
#define EALookupTable (core.ea_table)
|
||||||
case (OPCODE_NONE+_WHICH):
|
|
||||||
|
|
||||||
#define CASE_D(_WHICH) \
|
|
||||||
case (OPCODE_SIZE+_WHICH):
|
|
||||||
|
|
||||||
#define CASE_B(_WHICH) \
|
|
||||||
CASE_W(_WHICH) \
|
|
||||||
CASE_D(_WHICH)
|
|
||||||
|
|
||||||
#define CASE_0F_W(_WHICH) \
|
|
||||||
case ((OPCODE_0F|OPCODE_NONE)+_WHICH):
|
|
||||||
|
|
||||||
#define CASE_0F_D(_WHICH) \
|
|
||||||
case ((OPCODE_0F|OPCODE_SIZE)+_WHICH):
|
|
||||||
|
|
||||||
#define CASE_0F_B(_WHICH) \
|
|
||||||
CASE_0F_W(_WHICH) \
|
|
||||||
CASE_0F_D(_WHICH)
|
|
||||||
|
|
||||||
#define EALookupTable (*(core.ea_table))
|
|
||||||
|
|
||||||
Bits CPU_Core_Normal_Run(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;
|
|
||||||
lflags.type=t_UNKNOWN;
|
|
||||||
while (CPU_Cycles-->0) {
|
while (CPU_Cycles-->0) {
|
||||||
core.op_start=core.ip_lookup;
|
LOADIP;
|
||||||
core.opcode_index=core.index_default;
|
core.opcode_index=cpu.code.big*0x200;
|
||||||
core.prefixes=core.prefix_default;
|
core.prefixes=cpu.code.big;
|
||||||
|
core.ea_table=&EATable[cpu.code.big*256];
|
||||||
|
BaseDS=SegBase(ds);
|
||||||
|
BaseSS=SegBase(ss);
|
||||||
#if C_DEBUG
|
#if C_DEBUG
|
||||||
cycle_count++;
|
|
||||||
#if C_HEAVY_DEBUG
|
#if C_HEAVY_DEBUG
|
||||||
SAVEIP;
|
|
||||||
if (DEBUG_HeavyIsBreakpoint()) {
|
if (DEBUG_HeavyIsBreakpoint()) {
|
||||||
LEAVECORE;
|
FillFlags();
|
||||||
return debugCallback;
|
return debugCallback;
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
cycle_count++;
|
||||||
#endif
|
#endif
|
||||||
restart_prefix:
|
|
||||||
core.ea_table=EAPrefixTable[core.prefixes];
|
|
||||||
restart_opcode:
|
restart_opcode:
|
||||||
switch (core.opcode_index+Fetchb()) {
|
switch (core.opcode_index+Fetchb()) {
|
||||||
|
|
||||||
#include "core_normal/prefix_none.h"
|
#include "core_normal/prefix_none.h"
|
||||||
#include "core_normal/prefix_0f.h"
|
#include "core_normal/prefix_0f.h"
|
||||||
#include "core_normal/prefix_66.h"
|
#include "core_normal/prefix_66.h"
|
||||||
#include "core_normal/prefix_66_0f.h"
|
#include "core_normal/prefix_66_0f.h"
|
||||||
default:
|
default:
|
||||||
ADDIPFAST(-1);
|
illegal_opcode:
|
||||||
#if C_DEBUG
|
#if C_DEBUG
|
||||||
LOG_MSG("Unhandled code %X",core.opcode_index+Fetchb());
|
{
|
||||||
#else
|
Bitu len=(GETIP-reg_eip);
|
||||||
E_Exit("Unhandled CPU opcode");
|
LOADIP;
|
||||||
|
if (len>16) len=16;
|
||||||
|
char tempcode[16*2+1];char * writecode=tempcode;
|
||||||
|
for (;len>0;len--) {
|
||||||
|
sprintf(writecode,"%X",mem_readb(core.cseip++));
|
||||||
|
writecode+=2;
|
||||||
|
}
|
||||||
|
LOG(LOG_CPU,LOG_ERROR)("Illegal/Unhandled opcode %s",tempcode);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
CPU_Exception(6,0);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
SAVEIP;
|
||||||
}
|
}
|
||||||
decode_end:
|
FillFlags();
|
||||||
LEAVECORE;
|
return CBRET_NONE;
|
||||||
|
decode_end:
|
||||||
|
SAVEIP;
|
||||||
|
FillFlags();
|
||||||
return CBRET_NONE;
|
return CBRET_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,7 +194,7 @@ Bits CPU_Core_Normal_Trap_Run(void) {
|
|||||||
core.trap.skip=false;
|
core.trap.skip=false;
|
||||||
|
|
||||||
Bits ret=CPU_Core_Normal_Run();
|
Bits ret=CPU_Core_Normal_Run();
|
||||||
if (!core.trap.skip) CPU_SW_Interrupt(1,0);
|
if (!core.trap.skip) CPU_SW_Interrupt(1,reg_eip);
|
||||||
CPU_Cycles = oldCycles-1;
|
CPU_Cycles = oldCycles-1;
|
||||||
cpudecoder = &CPU_Core_Normal_Run;
|
cpudecoder = &CPU_Core_Normal_Run;
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
@ -141,17 +141,22 @@
|
|||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define POPSEG(_SEG_,_VAL_,_ESP_CHANGE_) \
|
#define CASE_W(_WHICH) \
|
||||||
if (CPU_SetSegGeneral(_SEG_,_VAL_)) { \
|
case (OPCODE_NONE+_WHICH):
|
||||||
LEAVECORE; \
|
|
||||||
reg_eip-=(core.ip_lookup-core.op_start);reg_esp-=_ESP_CHANGE_; \
|
|
||||||
CPU_StartException();goto decode_start; \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define LOADSEG(_SEG_,_SEG_VAL_) \
|
#define CASE_D(_WHICH) \
|
||||||
if (CPU_SetSegGeneral(_SEG_,_SEG_VAL_)) { \
|
case (OPCODE_SIZE+_WHICH):
|
||||||
LEAVECORE; \
|
|
||||||
reg_eip-=(core.ip_lookup-core.op_start); \
|
|
||||||
CPU_StartException();goto decode_start; \
|
|
||||||
} \
|
|
||||||
|
|
||||||
|
#define CASE_B(_WHICH) \
|
||||||
|
CASE_W(_WHICH) \
|
||||||
|
CASE_D(_WHICH)
|
||||||
|
|
||||||
|
#define CASE_0F_W(_WHICH) \
|
||||||
|
case ((OPCODE_0F|OPCODE_NONE)+_WHICH):
|
||||||
|
|
||||||
|
#define CASE_0F_D(_WHICH) \
|
||||||
|
case ((OPCODE_0F|OPCODE_SIZE)+_WHICH):
|
||||||
|
|
||||||
|
#define CASE_0F_B(_WHICH) \
|
||||||
|
CASE_0F_W(_WHICH) \
|
||||||
|
CASE_0F_D(_WHICH)
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
@ -45,7 +45,7 @@
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG(LOG_CPU,LOG_ERROR)("GRP6:Illegal call %2X",which);
|
goto illegal_opcode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -77,7 +77,7 @@
|
|||||||
break;
|
break;
|
||||||
case 0x06: /* LMSW */
|
case 0x06: /* LMSW */
|
||||||
limit=LoadMw(eaa);
|
limit=LoadMw(eaa);
|
||||||
if (!CPU_LMSW(limit)) goto decode_end;
|
if (CPU_LMSW(limit)) RUNEXCEPTION();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -88,11 +88,10 @@
|
|||||||
*earw=limit;
|
*earw=limit;
|
||||||
break;
|
break;
|
||||||
case 0x06: /* LMSW */
|
case 0x06: /* LMSW */
|
||||||
if (!CPU_LMSW(*earw)) goto decode_end;
|
if (CPU_LMSW(*earw)) RUNEXCEPTION();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG(LOG_CPU,LOG_ERROR)("Illegal group 7 RM subfunction %d",which);
|
goto illegal_opcode;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -100,7 +99,7 @@
|
|||||||
CASE_0F_W(0x02) /* LAR Gw,Ew */
|
CASE_0F_W(0x02) /* LAR Gw,Ew */
|
||||||
{
|
{
|
||||||
FillFlags();
|
FillFlags();
|
||||||
GetRMrw;Bitu ar;
|
GetRMrw;Bitu ar=*rmrw;
|
||||||
if (rm >= 0xc0) {
|
if (rm >= 0xc0) {
|
||||||
GetEArw;CPU_LAR(*earw,ar);
|
GetEArw;CPU_LAR(*earw,ar);
|
||||||
} else {
|
} else {
|
||||||
@ -112,7 +111,7 @@
|
|||||||
CASE_0F_W(0x03) /* LSL Gw,Ew */
|
CASE_0F_W(0x03) /* LSL Gw,Ew */
|
||||||
{
|
{
|
||||||
FillFlags();
|
FillFlags();
|
||||||
GetRMrw;Bitu limit;
|
GetRMrw;Bitu limit=*rmrw;
|
||||||
if (rm >= 0xc0) {
|
if (rm >= 0xc0) {
|
||||||
GetEArw;CPU_LSL(*earw,limit);
|
GetEArw;CPU_LSL(*earw,limit);
|
||||||
} else {
|
} else {
|
||||||
@ -154,11 +153,8 @@
|
|||||||
Bitu which=(rm >> 3) & 7;
|
Bitu which=(rm >> 3) & 7;
|
||||||
if (rm >= 0xc0 ) {
|
if (rm >= 0xc0 ) {
|
||||||
GetEArd;
|
GetEArd;
|
||||||
CPU_SET_CRX(which,*eard);
|
if (CPU_SET_CRX(which,*eard)) RUNEXCEPTION();
|
||||||
} else {
|
} else goto illegal_opcode;
|
||||||
GetEAa;
|
|
||||||
LOG(LOG_CPU,LOG_ERROR)("MOV CR%,XXX with non-register",which);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
CASE_0F_B(0x23) /* MOV DRx,Rd */
|
CASE_0F_B(0x23) /* MOV DRx,Rd */
|
||||||
@ -241,7 +237,7 @@
|
|||||||
CASE_0F_W(0xa0) /* PUSH FS */
|
CASE_0F_W(0xa0) /* PUSH FS */
|
||||||
Push_16(SegValue(fs));break;
|
Push_16(SegValue(fs));break;
|
||||||
CASE_0F_W(0xa1) /* POP FS */
|
CASE_0F_W(0xa1) /* POP FS */
|
||||||
POPSEG(fs,Pop_16(),2);
|
if (CPU_PopSeg(fs,false)) RUNEXCEPTION();
|
||||||
break;
|
break;
|
||||||
CASE_0F_B(0xa2) /* CPUID */
|
CASE_0F_B(0xa2) /* CPUID */
|
||||||
CPU_CPUID();break;
|
CPU_CPUID();break;
|
||||||
@ -268,7 +264,8 @@
|
|||||||
CASE_0F_W(0xa8) /* PUSH GS */
|
CASE_0F_W(0xa8) /* PUSH GS */
|
||||||
Push_16(SegValue(gs));break;
|
Push_16(SegValue(gs));break;
|
||||||
CASE_0F_W(0xa9) /* POP GS */
|
CASE_0F_W(0xa9) /* POP GS */
|
||||||
POPSEG(gs,Pop_16(),2);break;
|
if (CPU_PopSeg(gs,false)) RUNEXCEPTION();
|
||||||
|
break;
|
||||||
CASE_0F_W(0xab) /* BTS Ew,Gw */
|
CASE_0F_W(0xab) /* BTS Ew,Gw */
|
||||||
{
|
{
|
||||||
FillFlags();GetRMrw;
|
FillFlags();GetRMrw;
|
||||||
@ -297,7 +294,7 @@
|
|||||||
CASE_0F_W(0xb2) /* LSS Ew */
|
CASE_0F_W(0xb2) /* LSS Ew */
|
||||||
{
|
{
|
||||||
GetRMrw;GetEAa;
|
GetRMrw;GetEAa;
|
||||||
LOADSEG(ss,LoadMw(eaa+2));
|
if (CPU_SetSegGeneral(ss,LoadMw(eaa+2))) RUNEXCEPTION();
|
||||||
*rmrw=LoadMw(eaa);
|
*rmrw=LoadMw(eaa);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -320,14 +317,14 @@
|
|||||||
CASE_0F_W(0xb4) /* LFS Ew */
|
CASE_0F_W(0xb4) /* LFS Ew */
|
||||||
{
|
{
|
||||||
GetRMrw;GetEAa;
|
GetRMrw;GetEAa;
|
||||||
LOADSEG(fs,LoadMw(eaa+2));
|
if (CPU_SetSegGeneral(fs,LoadMw(eaa+2))) RUNEXCEPTION();
|
||||||
*rmrw=LoadMw(eaa);
|
*rmrw=LoadMw(eaa);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
CASE_0F_W(0xb5) /* LGS Ew */
|
CASE_0F_W(0xb5) /* LGS Ew */
|
||||||
{
|
{
|
||||||
GetRMrw;GetEAa;
|
GetRMrw;GetEAa;
|
||||||
LOADSEG(gs,LoadMw(eaa+2));
|
if (CPU_SetSegGeneral(gs,LoadMw(eaa+2))) RUNEXCEPTION();
|
||||||
*rmrw=LoadMw(eaa);
|
*rmrw=LoadMw(eaa);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
@ -25,7 +25,8 @@
|
|||||||
CASE_D(0x06) /* PUSH ES */
|
CASE_D(0x06) /* PUSH ES */
|
||||||
Push_32(SegValue(es));break;
|
Push_32(SegValue(es));break;
|
||||||
CASE_D(0x07) /* POP ES */
|
CASE_D(0x07) /* POP ES */
|
||||||
POPSEG(es,Pop_32(),4);break;
|
if (CPU_PopSeg(es,true)) RUNEXCEPTION();
|
||||||
|
break;
|
||||||
CASE_D(0x09) /* OR Ed,Gd */
|
CASE_D(0x09) /* OR Ed,Gd */
|
||||||
RMEdGd(ORD);break;
|
RMEdGd(ORD);break;
|
||||||
CASE_D(0x0b) /* OR Gd,Ed */
|
CASE_D(0x0b) /* OR Gd,Ed */
|
||||||
@ -43,7 +44,7 @@
|
|||||||
CASE_D(0x16) /* PUSH SS */
|
CASE_D(0x16) /* PUSH SS */
|
||||||
Push_32(SegValue(ss));break;
|
Push_32(SegValue(ss));break;
|
||||||
CASE_D(0x17) /* POP SS */
|
CASE_D(0x17) /* POP SS */
|
||||||
POPSEG(ss,Pop_32(),4);
|
if (CPU_PopSeg(ss,true)) RUNEXCEPTION();
|
||||||
CPU_Cycles++;
|
CPU_Cycles++;
|
||||||
break;
|
break;
|
||||||
CASE_D(0x19) /* SBB Ed,Gd */
|
CASE_D(0x19) /* SBB Ed,Gd */
|
||||||
@ -55,7 +56,8 @@
|
|||||||
CASE_D(0x1e) /* PUSH DS */
|
CASE_D(0x1e) /* PUSH DS */
|
||||||
Push_32(SegValue(ds));break;
|
Push_32(SegValue(ds));break;
|
||||||
CASE_D(0x1f) /* POP DS */
|
CASE_D(0x1f) /* POP DS */
|
||||||
POPSEG(ds,Pop_32(),4);break;
|
if (CPU_PopSeg(ds,true)) RUNEXCEPTION();
|
||||||
|
break;
|
||||||
CASE_D(0x21) /* AND Ed,Gd */
|
CASE_D(0x21) /* AND Ed,Gd */
|
||||||
RMEdGd(ANDD);break;
|
RMEdGd(ANDD);break;
|
||||||
CASE_D(0x23) /* AND Gd,Ed */
|
CASE_D(0x23) /* AND Gd,Ed */
|
||||||
@ -167,6 +169,7 @@
|
|||||||
break;
|
break;
|
||||||
CASE_D(0x63) /* ARPL Ed,Rd */
|
CASE_D(0x63) /* ARPL Ed,Rd */
|
||||||
{
|
{
|
||||||
|
if (((cpu.pmode) && (reg_flags & FLAG_VM)) || (!cpu.pmode)) goto illegal_opcode;
|
||||||
FillFlags();
|
FillFlags();
|
||||||
GetRMrw;
|
GetRMrw;
|
||||||
if (rm >= 0xc0 ) {
|
if (rm >= 0xc0 ) {
|
||||||
@ -190,6 +193,12 @@
|
|||||||
CASE_D(0x6b) /* IMUL Gd,Ed,Ib */
|
CASE_D(0x6b) /* IMUL Gd,Ed,Ib */
|
||||||
RMGdEdOp3(DIMULD,Fetchbs());
|
RMGdEdOp3(DIMULD,Fetchbs());
|
||||||
break;
|
break;
|
||||||
|
CASE_D(0x6d) /* INSD */
|
||||||
|
if (CPU_IO_Exception(reg_dx,4)) RUNEXCEPTION();
|
||||||
|
DoString(R_INSD);break;
|
||||||
|
CASE_D(0x6f) /* OUTSD */
|
||||||
|
if (CPU_IO_Exception(reg_dx,4)) RUNEXCEPTION();
|
||||||
|
DoString(R_OUTSD);break;
|
||||||
CASE_D(0x70) /* JO */
|
CASE_D(0x70) /* JO */
|
||||||
JumpCond32_b(TFLG_O);break;
|
JumpCond32_b(TFLG_O);break;
|
||||||
CASE_D(0x71) /* JNO */
|
CASE_D(0x71) /* JNO */
|
||||||
@ -332,12 +341,12 @@
|
|||||||
CASE_D(0x8d) /* LEA Gd */
|
CASE_D(0x8d) /* LEA Gd */
|
||||||
{
|
{
|
||||||
//Little hack to always use segprefixed version
|
//Little hack to always use segprefixed version
|
||||||
core.seg_prefix_base=0;
|
|
||||||
GetRMrd;
|
GetRMrd;
|
||||||
|
BaseDS=BaseSS=0;
|
||||||
if (TEST_PREFIX_ADDR) {
|
if (TEST_PREFIX_ADDR) {
|
||||||
*rmrd=(Bit32u)(*GetEA_SEG_ADDR[rm])();
|
*rmrd=(Bit32u)(*EATable[256+rm])();
|
||||||
} else {
|
} else {
|
||||||
*rmrd=(Bit32u)(*GetEA_SEG[rm])();
|
*rmrd=(Bit32u)(*EATable[rm])();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -378,21 +387,17 @@
|
|||||||
CASE_D(0x9a) /* CALL FAR Ad */
|
CASE_D(0x9a) /* CALL FAR Ad */
|
||||||
{
|
{
|
||||||
Bit32u newip=Fetchd();Bit16u newcs=Fetchw();
|
Bit32u newip=Fetchd();Bit16u newcs=Fetchw();
|
||||||
LEAVECORE;
|
FillFlags();
|
||||||
CPU_CALL(true,newcs,newip);
|
CPU_CALL(true,newcs,newip,GETIP);
|
||||||
goto decode_start;
|
continue;
|
||||||
}
|
}
|
||||||
CASE_D(0x9c) /* PUSHFD */
|
CASE_D(0x9c) /* PUSHFD */
|
||||||
FillFlags();
|
FillFlags();
|
||||||
Push_32(reg_flags);
|
if (CPU_PUSHF(true)) RUNEXCEPTION();
|
||||||
break;
|
break;
|
||||||
CASE_D(0x9d) /* POPFD */
|
CASE_D(0x9d) /* POPFD */
|
||||||
if ((reg_flags & FLAG_VM) && ((reg_flags & FLAG_IOPL)!=FLAG_IOPL)) {
|
if (CPU_POPF(true)) RUNEXCEPTION();
|
||||||
LEAVECORE;reg_eip-=core.ip_lookup-core.op_start;
|
lflags.type=t_UNKNOWN;
|
||||||
CPU_Exception(13,0);
|
|
||||||
goto decode_start;
|
|
||||||
}
|
|
||||||
SETFLAGSd(Pop_32())
|
|
||||||
#if CPU_TRAP_CHECK
|
#if CPU_TRAP_CHECK
|
||||||
if (GETFLAG(TF)) {
|
if (GETFLAG(TF)) {
|
||||||
cpudecoder=CPU_Core_Normal_Trap_Run;
|
cpudecoder=CPU_Core_Normal_Trap_Run;
|
||||||
@ -402,7 +407,6 @@
|
|||||||
#if CPU_PIC_CHECK
|
#if CPU_PIC_CHECK
|
||||||
if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end;
|
if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
break;
|
break;
|
||||||
CASE_D(0xa1) /* MOV EAX,Od */
|
CASE_D(0xa1) /* MOV EAX,Od */
|
||||||
{
|
{
|
||||||
@ -447,25 +451,23 @@
|
|||||||
CASE_D(0xc1) /* GRP2 Ed,Ib */
|
CASE_D(0xc1) /* GRP2 Ed,Ib */
|
||||||
GRP2D(Fetchb());break;
|
GRP2D(Fetchb());break;
|
||||||
CASE_D(0xc2) /* RETN Iw */
|
CASE_D(0xc2) /* RETN Iw */
|
||||||
{
|
reg_eip=Pop_32();
|
||||||
Bit16u addsp=Fetchw();
|
reg_esp+=Fetchw();
|
||||||
SETIP(Pop_32());reg_esp+=addsp;
|
continue;
|
||||||
break;
|
|
||||||
}
|
|
||||||
CASE_D(0xc3) /* RETN */
|
CASE_D(0xc3) /* RETN */
|
||||||
SETIP(Pop_32());
|
reg_eip=Pop_32();
|
||||||
break;
|
continue;
|
||||||
CASE_D(0xc4) /* LES */
|
CASE_D(0xc4) /* LES */
|
||||||
{
|
{
|
||||||
GetRMrd;GetEAa;
|
GetRMrd;GetEAa;
|
||||||
LOADSEG(es,LoadMw(eaa+4));
|
if (CPU_SetSegGeneral(es,LoadMw(eaa+4))) RUNEXCEPTION();
|
||||||
*rmrd=LoadMd(eaa);
|
*rmrd=LoadMd(eaa);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
CASE_D(0xc5) /* LDS */
|
CASE_D(0xc5) /* LDS */
|
||||||
{
|
{
|
||||||
GetRMrd;GetEAa;
|
GetRMrd;GetEAa;
|
||||||
LOADSEG(ds,LoadMw(eaa+4));
|
if (CPU_SetSegGeneral(ds,LoadMw(eaa+4))) RUNEXCEPTION();
|
||||||
*rmrd=LoadMd(eaa);
|
*rmrd=LoadMd(eaa);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -478,36 +480,11 @@
|
|||||||
}
|
}
|
||||||
CASE_D(0xc8) /* ENTER Iw,Ib */
|
CASE_D(0xc8) /* ENTER Iw,Ib */
|
||||||
{
|
{
|
||||||
Bitu bytes=Fetchw();Bitu level=Fetchb() & 0x1f;
|
Bitu bytes=Fetchw();
|
||||||
Bitu frame_ptr=reg_esp-4;
|
Bitu level=Fetchb();
|
||||||
if (cpu.stack.big) {
|
CPU_ENTER(true,bytes,level);
|
||||||
reg_esp-=4;
|
|
||||||
mem_writed(SegBase(ss)+reg_esp,reg_ebp);
|
|
||||||
for (Bitu i=1;i<level;i++) {
|
|
||||||
reg_ebp-=4;reg_esp-=4;
|
|
||||||
mem_writed(SegBase(ss)+reg_esp,mem_readd(SegBase(ss)+reg_ebp));
|
|
||||||
}
|
}
|
||||||
if (level) {
|
|
||||||
reg_esp-=4;
|
|
||||||
mem_writed(SegBase(ss)+reg_esp,(Bit32u)frame_ptr);
|
|
||||||
}
|
|
||||||
reg_esp-=bytes;
|
|
||||||
} else {
|
|
||||||
reg_sp-=4;
|
|
||||||
mem_writed(SegBase(ss)+reg_sp,reg_ebp);
|
|
||||||
for (Bitu i=1;i<level;i++) {
|
|
||||||
reg_bp-=4;reg_sp-=4;
|
|
||||||
mem_writed(SegBase(ss)+reg_sp,mem_readd(SegBase(ss)+reg_bp));
|
|
||||||
}
|
|
||||||
if (level) {
|
|
||||||
reg_sp-=4;
|
|
||||||
mem_writed(SegBase(ss)+reg_sp,(Bit32u)frame_ptr);
|
|
||||||
}
|
|
||||||
reg_sp-=bytes;
|
|
||||||
}
|
|
||||||
reg_ebp=frame_ptr;
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
CASE_D(0xc9) /* LEAVE */
|
CASE_D(0xc9) /* LEAVE */
|
||||||
reg_esp&=~cpu.stack.mask;
|
reg_esp&=~cpu.stack.mask;
|
||||||
reg_esp|=(reg_ebp&cpu.stack.mask);
|
reg_esp|=(reg_ebp&cpu.stack.mask);
|
||||||
@ -516,20 +493,20 @@
|
|||||||
CASE_D(0xca) /* RETF Iw */
|
CASE_D(0xca) /* RETF Iw */
|
||||||
{
|
{
|
||||||
Bitu words=Fetchw();
|
Bitu words=Fetchw();
|
||||||
LEAVECORE;
|
FillFlags();
|
||||||
CPU_RET(true,words,core.ip_lookup-core.op_start);
|
CPU_RET(true,words,GETIP);
|
||||||
goto decode_start;
|
continue;
|
||||||
}
|
}
|
||||||
CASE_D(0xcb) /* RETF */
|
CASE_D(0xcb) /* RETF */
|
||||||
{
|
{
|
||||||
LEAVECORE;
|
FillFlags();
|
||||||
CPU_RET(true,0,core.ip_lookup-core.op_start);
|
CPU_RET(true,0,GETIP);
|
||||||
goto decode_start;
|
continue;
|
||||||
}
|
}
|
||||||
CASE_D(0xcf) /* IRET */
|
CASE_D(0xcf) /* IRET */
|
||||||
{
|
{
|
||||||
LEAVECORE;
|
FillFlags();
|
||||||
CPU_IRET(true);
|
CPU_IRET(true,GETIP);
|
||||||
#if CPU_TRAP_CHECK
|
#if CPU_TRAP_CHECK
|
||||||
if (GETFLAG(TF)) {
|
if (GETFLAG(TF)) {
|
||||||
cpudecoder=CPU_Core_Normal_Trap_Run;
|
cpudecoder=CPU_Core_Normal_Trap_Run;
|
||||||
@ -539,36 +516,79 @@
|
|||||||
#if CPU_PIC_CHECK
|
#if CPU_PIC_CHECK
|
||||||
if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE;
|
if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE;
|
||||||
#endif
|
#endif
|
||||||
//TODO TF check
|
continue;
|
||||||
goto decode_start;
|
|
||||||
}
|
}
|
||||||
CASE_D(0xd1) /* GRP2 Ed,1 */
|
CASE_D(0xd1) /* GRP2 Ed,1 */
|
||||||
GRP2D(1);break;
|
GRP2D(1);break;
|
||||||
CASE_D(0xd3) /* GRP2 Ed,CL */
|
CASE_D(0xd3) /* GRP2 Ed,CL */
|
||||||
GRP2D(reg_cl);break;
|
GRP2D(reg_cl);break;
|
||||||
|
CASE_D(0xe0) /* LOOPNZ */
|
||||||
|
if (TEST_PREFIX_ADDR) {
|
||||||
|
JumpCond32_b(--reg_ecx && !get_ZF());
|
||||||
|
} else {
|
||||||
|
JumpCond32_b(--reg_cx && !get_ZF());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
CASE_D(0xe1) /* LOOPZ */
|
||||||
|
if (TEST_PREFIX_ADDR) {
|
||||||
|
JumpCond32_b(--reg_ecx && get_ZF());
|
||||||
|
} else {
|
||||||
|
JumpCond32_b(--reg_cx && get_ZF());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
CASE_D(0xe2) /* LOOP */
|
||||||
|
if (TEST_PREFIX_ADDR) {
|
||||||
|
JumpCond32_b(--reg_ecx);
|
||||||
|
} else {
|
||||||
|
JumpCond32_b(--reg_cx);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
CASE_D(0xe3) /* JCXZ */
|
||||||
|
JumpCond32_b(!(reg_ecx & AddrMaskTable[core.prefixes& PREFIX_ADDR]));
|
||||||
|
break;
|
||||||
CASE_D(0xe5) /* IN EAX,Ib */
|
CASE_D(0xe5) /* IN EAX,Ib */
|
||||||
reg_eax=IO_ReadD(Fetchb());
|
|
||||||
break;
|
|
||||||
CASE_D(0xe7) /* OUT Ib,EAX */
|
|
||||||
IO_WriteD(Fetchb(),reg_eax);
|
|
||||||
break;
|
|
||||||
CASE_D(0xe8) /* CALL Jd */
|
|
||||||
{
|
{
|
||||||
Bit32s newip=Fetchds();
|
Bitu port=Fetchb();
|
||||||
Push_32((Bit32u)GETIP);
|
if (CPU_IO_Exception(port,4)) RUNEXCEPTION();
|
||||||
ADDIPd(newip);
|
reg_eax=IO_ReadD(port);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
CASE_D(0xe9) /* JMP Jd */
|
CASE_D(0xe7) /* OUT Ib,EAX */
|
||||||
ADDIPd(Fetchds());
|
{
|
||||||
|
Bitu port=Fetchb();
|
||||||
|
if (CPU_IO_Exception(port,4)) RUNEXCEPTION();
|
||||||
|
IO_WriteD(port,reg_eax);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
CASE_D(0xe8) /* CALL Jd */
|
||||||
|
{
|
||||||
|
Bit32s addip=Fetchds();
|
||||||
|
SAVEIP;
|
||||||
|
Push_32(reg_eip);
|
||||||
|
reg_eip+=addip;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
CASE_D(0xe9) /* JMP Jd */
|
||||||
|
{
|
||||||
|
Bit32s addip=Fetchds();
|
||||||
|
SAVEIP;
|
||||||
|
reg_eip+=addip;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
CASE_D(0xea) /* JMP Ad */
|
CASE_D(0xea) /* JMP Ad */
|
||||||
{
|
{
|
||||||
Bit32u newip=Fetchd();
|
Bit32u newip=Fetchd();
|
||||||
Bit16u newcs=Fetchw();
|
Bit16u newcs=Fetchw();
|
||||||
LEAVECORE;
|
FillFlags();
|
||||||
CPU_JMP(true,newcs,newip,core.ip_lookup-core.op_start);
|
CPU_JMP(true,newcs,newip,GETIP);
|
||||||
goto decode_start;
|
continue;
|
||||||
|
}
|
||||||
|
CASE_D(0xeb) /* JMP Jb */
|
||||||
|
{
|
||||||
|
Bit32s addip=Fetchbs();
|
||||||
|
SAVEIP;
|
||||||
|
reg_eip+=addip;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
CASE_D(0xed) /* IN EAX,DX */
|
CASE_D(0xed) /* IN EAX,DX */
|
||||||
reg_eax=IO_ReadD(reg_dx);
|
reg_eax=IO_ReadD(reg_dx);
|
||||||
@ -631,31 +651,31 @@
|
|||||||
RMEd(DECD);
|
RMEd(DECD);
|
||||||
break;
|
break;
|
||||||
case 0x02: /* CALL NEAR Ed */
|
case 0x02: /* CALL NEAR Ed */
|
||||||
if (rm >= 0xc0 ) {GetEArd;Push_32(GETIP);SETIP(*eard);}
|
if (rm >= 0xc0 ) {GetEArd;reg_eip=*eard;}
|
||||||
else {GetEAa;Push_32(GETIP);SETIP(LoadMd(eaa));}
|
else {GetEAa;reg_eip=LoadMd(eaa);}
|
||||||
break;
|
Push_32(GETIP);
|
||||||
|
continue;
|
||||||
case 0x03: /* CALL FAR Ed */
|
case 0x03: /* CALL FAR Ed */
|
||||||
{
|
{
|
||||||
GetEAa;
|
GetEAa;
|
||||||
Bit32u newip=LoadMd(eaa);
|
Bit32u newip=LoadMd(eaa);
|
||||||
Bit16u newcs=LoadMw(eaa+4);
|
Bit16u newcs=LoadMw(eaa+4);
|
||||||
LEAVECORE;
|
FillFlags();
|
||||||
CPU_CALL(true,newcs,newip);
|
CPU_CALL(true,newcs,newip,GETIP);
|
||||||
goto decode_start;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case 0x04: /* JMP NEAR Ed */
|
case 0x04: /* JMP NEAR Ed */
|
||||||
if (rm >= 0xc0 ) {GetEArd;SETIP(*eard);}
|
if (rm >= 0xc0 ) {GetEArd;reg_eip=*eard;}
|
||||||
else {GetEAa;SETIP(LoadMd(eaa));}
|
else {GetEAa;reg_eip=LoadMd(eaa);}
|
||||||
break;
|
continue;
|
||||||
case 0x05: /* JMP FAR Ed */
|
case 0x05: /* JMP FAR Ed */
|
||||||
{
|
{
|
||||||
GetEAa;
|
GetEAa;
|
||||||
Bit32u newip=LoadMd(eaa);
|
Bit32u newip=LoadMd(eaa);
|
||||||
Bit16u newcs=LoadMw(eaa+4);
|
Bit16u newcs=LoadMw(eaa+4);
|
||||||
LEAVECORE;
|
FillFlags();
|
||||||
CPU_JMP(true,newcs,newip,core.ip_lookup-core.op_start);
|
CPU_JMP(true,newcs,newip,GETIP);
|
||||||
goto decode_start;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x06: /* Push Ed */
|
case 0x06: /* Push Ed */
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
@ -101,7 +101,7 @@
|
|||||||
CASE_0F_D(0x02) /* LAR Gd,Ed */
|
CASE_0F_D(0x02) /* LAR Gd,Ed */
|
||||||
{
|
{
|
||||||
FillFlags();
|
FillFlags();
|
||||||
GetRMrd;Bitu ar;
|
GetRMrd;Bitu ar=*rmrd;
|
||||||
if (rm >= 0xc0) {
|
if (rm >= 0xc0) {
|
||||||
GetEArw;CPU_LAR(*earw,ar);
|
GetEArw;CPU_LAR(*earw,ar);
|
||||||
} else {
|
} else {
|
||||||
@ -113,7 +113,7 @@
|
|||||||
CASE_0F_D(0x03) /* LSL Gd,Ew */
|
CASE_0F_D(0x03) /* LSL Gd,Ew */
|
||||||
{
|
{
|
||||||
FillFlags();
|
FillFlags();
|
||||||
GetRMrd;Bitu limit;
|
GetRMrd;Bitu limit=*rmrd;
|
||||||
/* Just load 16-bit values for selectors */
|
/* Just load 16-bit values for selectors */
|
||||||
if (rm >= 0xc0) {
|
if (rm >= 0xc0) {
|
||||||
GetEArw;CPU_LSL(*earw,limit);
|
GetEArw;CPU_LSL(*earw,limit);
|
||||||
@ -159,7 +159,8 @@
|
|||||||
CASE_0F_D(0xa0) /* PUSH FS */
|
CASE_0F_D(0xa0) /* PUSH FS */
|
||||||
Push_32(SegValue(fs));break;
|
Push_32(SegValue(fs));break;
|
||||||
CASE_0F_D(0xa1) /* POP FS */
|
CASE_0F_D(0xa1) /* POP FS */
|
||||||
POPSEG(fs,Pop_32(),4);break;
|
if (CPU_PopSeg(fs,true)) RUNEXCEPTION();
|
||||||
|
break;
|
||||||
CASE_0F_D(0xa3) /* BT Ed,Gd */
|
CASE_0F_D(0xa3) /* BT Ed,Gd */
|
||||||
{
|
{
|
||||||
FillFlags();GetRMrd;
|
FillFlags();GetRMrd;
|
||||||
@ -183,7 +184,8 @@
|
|||||||
CASE_0F_D(0xa8) /* PUSH GS */
|
CASE_0F_D(0xa8) /* PUSH GS */
|
||||||
Push_32(SegValue(gs));break;
|
Push_32(SegValue(gs));break;
|
||||||
CASE_0F_D(0xa9) /* POP GS */
|
CASE_0F_D(0xa9) /* POP GS */
|
||||||
POPSEG(gs,Pop_32(),4);break;
|
if (CPU_PopSeg(gs,true)) RUNEXCEPTION();
|
||||||
|
break;
|
||||||
CASE_0F_D(0xab) /* BTS Ed,Gd */
|
CASE_0F_D(0xab) /* BTS Ed,Gd */
|
||||||
{
|
{
|
||||||
FillFlags();GetRMrd;
|
FillFlags();GetRMrd;
|
||||||
@ -215,7 +217,7 @@
|
|||||||
CASE_0F_D(0xb2) /* LSS Ed */
|
CASE_0F_D(0xb2) /* LSS Ed */
|
||||||
{
|
{
|
||||||
GetRMrd;GetEAa;
|
GetRMrd;GetEAa;
|
||||||
LOADSEG(ss,LoadMw(eaa+4));
|
if (CPU_SetSegGeneral(ss,LoadMw(eaa+4))) RUNEXCEPTION();
|
||||||
*rmrd=LoadMd(eaa);
|
*rmrd=LoadMd(eaa);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -238,14 +240,14 @@
|
|||||||
CASE_0F_D(0xb4) /* LFS Ed */
|
CASE_0F_D(0xb4) /* LFS Ed */
|
||||||
{
|
{
|
||||||
GetRMrd;GetEAa;
|
GetRMrd;GetEAa;
|
||||||
LOADSEG(fs,LoadMw(eaa+4));
|
if (CPU_SetSegGeneral(fs,LoadMw(eaa+4))) RUNEXCEPTION();
|
||||||
*rmrd=LoadMd(eaa);
|
*rmrd=LoadMd(eaa);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
CASE_0F_D(0xb5) /* LGS Ed */
|
CASE_0F_D(0xb5) /* LGS Ed */
|
||||||
{
|
{
|
||||||
GetRMrd;GetEAa;
|
GetRMrd;GetEAa;
|
||||||
LOADSEG(gs,LoadMw(eaa+4));
|
if (CPU_SetSegGeneral(gs,LoadMw(eaa+4))) RUNEXCEPTION();
|
||||||
*rmrd=LoadMd(eaa);
|
*rmrd=LoadMd(eaa);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
@ -31,7 +31,8 @@
|
|||||||
CASE_W(0x06) /* PUSH ES */
|
CASE_W(0x06) /* PUSH ES */
|
||||||
Push_16(SegValue(es));break;
|
Push_16(SegValue(es));break;
|
||||||
CASE_W(0x07) /* POP ES */
|
CASE_W(0x07) /* POP ES */
|
||||||
POPSEG(es,Pop_16(),2);break;
|
if (CPU_PopSeg(es,false)) RUNEXCEPTION();
|
||||||
|
break;
|
||||||
CASE_B(0x08) /* OR Eb,Gb */
|
CASE_B(0x08) /* OR Eb,Gb */
|
||||||
RMEbGb(ORB);break;
|
RMEbGb(ORB);break;
|
||||||
CASE_W(0x09) /* OR Ew,Gw */
|
CASE_W(0x09) /* OR Ew,Gw */
|
||||||
@ -65,7 +66,7 @@
|
|||||||
CASE_W(0x16) /* PUSH SS */
|
CASE_W(0x16) /* PUSH SS */
|
||||||
Push_16(SegValue(ss));break;
|
Push_16(SegValue(ss));break;
|
||||||
CASE_W(0x17) /* POP SS */
|
CASE_W(0x17) /* POP SS */
|
||||||
POPSEG(ss,Pop_16(),2);
|
if (CPU_PopSeg(ss,false)) RUNEXCEPTION();
|
||||||
CPU_Cycles++; //Always do another instruction
|
CPU_Cycles++; //Always do another instruction
|
||||||
break;
|
break;
|
||||||
CASE_B(0x18) /* SBB Eb,Gb */
|
CASE_B(0x18) /* SBB Eb,Gb */
|
||||||
@ -83,7 +84,7 @@
|
|||||||
CASE_W(0x1e) /* PUSH DS */
|
CASE_W(0x1e) /* PUSH DS */
|
||||||
Push_16(SegValue(ds));break;
|
Push_16(SegValue(ds));break;
|
||||||
CASE_W(0x1f) /* POP DS */
|
CASE_W(0x1f) /* POP DS */
|
||||||
POPSEG(ds,Pop_16(),2);
|
if (CPU_PopSeg(ds,false)) RUNEXCEPTION();
|
||||||
break;
|
break;
|
||||||
CASE_B(0x20) /* AND Eb,Gb */
|
CASE_B(0x20) /* AND Eb,Gb */
|
||||||
RMEbGb(ANDB);break;
|
RMEbGb(ANDB);break;
|
||||||
@ -237,6 +238,7 @@
|
|||||||
break;
|
break;
|
||||||
CASE_W(0x63) /* ARPL Ew,Rw */
|
CASE_W(0x63) /* ARPL Ew,Rw */
|
||||||
{
|
{
|
||||||
|
if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegal_opcode;
|
||||||
FillFlags();
|
FillFlags();
|
||||||
GetRMrw;
|
GetRMrw;
|
||||||
if (rm >= 0xc0 ) {
|
if (rm >= 0xc0 ) {
|
||||||
@ -255,7 +257,7 @@
|
|||||||
CASE_B(0x65) /* SEG GS: */
|
CASE_B(0x65) /* SEG GS: */
|
||||||
DO_PREFIX_SEG(gs);break;
|
DO_PREFIX_SEG(gs);break;
|
||||||
CASE_B(0x66) /* Operand Size Prefix */
|
CASE_B(0x66) /* Operand Size Prefix */
|
||||||
core.opcode_index=core.index_default^OPCODE_SIZE;
|
core.opcode_index=(cpu.code.big^0x1)*0x200;
|
||||||
goto restart_opcode;
|
goto restart_opcode;
|
||||||
CASE_B(0x67) /* Address Size Prefix */
|
CASE_B(0x67) /* Address Size Prefix */
|
||||||
DO_PREFIX_ADDR();
|
DO_PREFIX_ADDR();
|
||||||
@ -271,12 +273,16 @@
|
|||||||
RMGwEwOp3(DIMULW,Fetchbs());
|
RMGwEwOp3(DIMULW,Fetchbs());
|
||||||
break;
|
break;
|
||||||
CASE_B(0x6c) /* INSB */
|
CASE_B(0x6c) /* INSB */
|
||||||
|
if (CPU_IO_Exception(reg_dx,1)) RUNEXCEPTION();
|
||||||
DoString(R_INSB);break;
|
DoString(R_INSB);break;
|
||||||
CASE_W(0x6d) /* INSW */
|
CASE_W(0x6d) /* INSW */
|
||||||
|
if (CPU_IO_Exception(reg_dx,2)) RUNEXCEPTION();
|
||||||
DoString(R_INSW);break;
|
DoString(R_INSW);break;
|
||||||
CASE_B(0x6e) /* OUTSB */
|
CASE_B(0x6e) /* OUTSB */
|
||||||
|
if (CPU_IO_Exception(reg_dx,1)) RUNEXCEPTION();
|
||||||
DoString(R_OUTSB);break;
|
DoString(R_OUTSB);break;
|
||||||
CASE_W(0x6f) /* OUTSW */
|
CASE_W(0x6f) /* OUTSW */
|
||||||
|
if (CPU_IO_Exception(reg_dx,2)) RUNEXCEPTION();
|
||||||
DoString(R_OUTSW);break;
|
DoString(R_OUTSW);break;
|
||||||
CASE_W(0x70) /* JO */
|
CASE_W(0x70) /* JO */
|
||||||
JumpCond16_b(TFLG_O);break;
|
JumpCond16_b(TFLG_O);break;
|
||||||
@ -476,12 +482,12 @@
|
|||||||
CASE_W(0x8d) /* LEA Gw */
|
CASE_W(0x8d) /* LEA Gw */
|
||||||
{
|
{
|
||||||
//Little hack to always use segprefixed version
|
//Little hack to always use segprefixed version
|
||||||
core.seg_prefix_base=0;
|
BaseDS=BaseSS=0;
|
||||||
GetRMrw;
|
GetRMrw;
|
||||||
if (TEST_PREFIX_ADDR) {
|
if (TEST_PREFIX_ADDR) {
|
||||||
*rmrw=(Bit16u)(*GetEA_SEG_ADDR[rm])();
|
*rmrw=(Bit16u)(*EATable[256+rm])();
|
||||||
} else {
|
} else {
|
||||||
*rmrw=(Bit16u)(*GetEA_SEG[rm])();
|
*rmrw=(Bit16u)(*EATable[rm])();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -497,13 +503,10 @@
|
|||||||
case 0x03: /* MOV DS,Ew */
|
case 0x03: /* MOV DS,Ew */
|
||||||
case 0x05: /* MOV GS,Ew */
|
case 0x05: /* MOV GS,Ew */
|
||||||
case 0x04: /* MOV FS,Ew */
|
case 0x04: /* MOV FS,Ew */
|
||||||
LOADSEG((SegNames)which,val);
|
if (CPU_SetSegGeneral((SegNames)which,val)) RUNEXCEPTION();
|
||||||
break;
|
|
||||||
case 0x01: /* MOV CS,Ew Illegal*/
|
|
||||||
E_Exit("CPU:Illegal MOV CS Call");
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
E_Exit("CPU:8E:Illegal RM Byte");
|
goto illegal_opcode;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -545,24 +548,20 @@
|
|||||||
break;
|
break;
|
||||||
CASE_W(0x9a) /* CALL Ap */
|
CASE_W(0x9a) /* CALL Ap */
|
||||||
{
|
{
|
||||||
|
FillFlags();
|
||||||
Bit16u newip=Fetchw();Bit16u newcs=Fetchw();
|
Bit16u newip=Fetchw();Bit16u newcs=Fetchw();
|
||||||
LEAVECORE;
|
CPU_CALL(false,newcs,newip,GETIP);
|
||||||
CPU_CALL(false,newcs,newip,core.ip_lookup-core.op_start);
|
continue;
|
||||||
goto decode_start;
|
|
||||||
}
|
}
|
||||||
CASE_B(0x9b) /* WAIT */
|
CASE_B(0x9b) /* WAIT */
|
||||||
break; /* No waiting here */
|
break; /* No waiting here */
|
||||||
CASE_W(0x9c) /* PUSHF */
|
CASE_W(0x9c) /* PUSHF */
|
||||||
FillFlags();
|
FillFlags();
|
||||||
Push_16(reg_flags);
|
if (CPU_PUSHF(false)) RUNEXCEPTION();
|
||||||
break;
|
break;
|
||||||
CASE_W(0x9d) /* POPF */
|
CASE_W(0x9d) /* POPF */
|
||||||
if ((reg_flags & FLAG_VM) && ((reg_flags & FLAG_IOPL)!=FLAG_IOPL)) {
|
if (CPU_POPF(false)) RUNEXCEPTION();
|
||||||
LEAVECORE;reg_eip-=core.ip_lookup-core.op_start;
|
lflags.type=t_UNKNOWN;
|
||||||
CPU_Exception(13,0);
|
|
||||||
goto decode_start;
|
|
||||||
}
|
|
||||||
SETFLAGSw(Pop_16());
|
|
||||||
#if CPU_TRAP_CHECK
|
#if CPU_TRAP_CHECK
|
||||||
if (GETFLAG(TF)) {
|
if (GETFLAG(TF)) {
|
||||||
cpudecoder=CPU_Core_Normal_Trap_Run;
|
cpudecoder=CPU_Core_Normal_Trap_Run;
|
||||||
@ -665,25 +664,23 @@
|
|||||||
CASE_W(0xc1) /* GRP2 Ew,Ib */
|
CASE_W(0xc1) /* GRP2 Ew,Ib */
|
||||||
GRP2W(Fetchb());break;
|
GRP2W(Fetchb());break;
|
||||||
CASE_W(0xc2) /* RETN Iw */
|
CASE_W(0xc2) /* RETN Iw */
|
||||||
{
|
reg_eip=Pop_16();
|
||||||
Bit16u addsp=Fetchw();
|
reg_esp+=Fetchw();
|
||||||
SETIP(Pop_16());reg_esp+=addsp;
|
continue;
|
||||||
break;
|
|
||||||
}
|
|
||||||
CASE_W(0xc3) /* RETN */
|
CASE_W(0xc3) /* RETN */
|
||||||
SETIP(Pop_16());
|
reg_eip=Pop_16();
|
||||||
break;
|
continue;
|
||||||
CASE_W(0xc4) /* LES */
|
CASE_W(0xc4) /* LES */
|
||||||
{
|
{
|
||||||
GetRMrw;GetEAa;
|
GetRMrw;GetEAa;
|
||||||
LOADSEG(es,LoadMw(eaa+2));
|
if (CPU_SetSegGeneral(es,LoadMw(eaa+2))) RUNEXCEPTION();
|
||||||
*rmrw=LoadMw(eaa);
|
*rmrw=LoadMw(eaa);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
CASE_W(0xc5) /* LDS */
|
CASE_W(0xc5) /* LDS */
|
||||||
{
|
{
|
||||||
GetRMrw;GetEAa;
|
GetRMrw;GetEAa;
|
||||||
LOADSEG(ds,LoadMw(eaa+2));
|
if (CPU_SetSegGeneral(ds,LoadMw(eaa+2))) RUNEXCEPTION();
|
||||||
*rmrw=LoadMw(eaa);
|
*rmrw=LoadMw(eaa);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -703,36 +700,11 @@
|
|||||||
}
|
}
|
||||||
CASE_W(0xc8) /* ENTER Iw,Ib */
|
CASE_W(0xc8) /* ENTER Iw,Ib */
|
||||||
{
|
{
|
||||||
Bitu bytes=Fetchw();Bitu level=Fetchb() & 0x1f;
|
Bitu bytes=Fetchw();
|
||||||
Bitu frame_ptr=reg_esp-2;
|
Bitu level=Fetchb();
|
||||||
if (cpu.stack.big) {
|
CPU_ENTER(false,bytes,level);
|
||||||
reg_esp-=2;
|
|
||||||
mem_writew(SegBase(ss)+reg_esp,reg_bp);
|
|
||||||
for (Bitu i=1;i<level;i++) {
|
|
||||||
reg_ebp-=2;reg_esp-=2;
|
|
||||||
mem_writew(SegBase(ss)+reg_esp,mem_readw(SegBase(ss)+reg_ebp));
|
|
||||||
}
|
}
|
||||||
if (level) {
|
|
||||||
reg_esp-=2;
|
|
||||||
mem_writew(SegBase(ss)+reg_esp,(Bit16u)frame_ptr);
|
|
||||||
}
|
|
||||||
reg_esp-=bytes;
|
|
||||||
} else {
|
|
||||||
reg_sp-=2;
|
|
||||||
mem_writew(SegBase(ss)+reg_sp,reg_bp);
|
|
||||||
for (Bitu i=1;i<level;i++) {
|
|
||||||
reg_bp-=2;reg_sp-=2;
|
|
||||||
mem_writew(SegBase(ss)+reg_sp,mem_readw(SegBase(ss)+reg_bp));
|
|
||||||
}
|
|
||||||
if (level) {
|
|
||||||
reg_sp-=2;
|
|
||||||
mem_writew(SegBase(ss)+reg_sp,(Bit16u)frame_ptr);
|
|
||||||
}
|
|
||||||
reg_sp-=bytes;
|
|
||||||
}
|
|
||||||
reg_bp=frame_ptr;
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
CASE_W(0xc9) /* LEAVE */
|
CASE_W(0xc9) /* LEAVE */
|
||||||
reg_esp&=~cpu.stack.mask;
|
reg_esp&=~cpu.stack.mask;
|
||||||
reg_esp|=(reg_ebp&cpu.stack.mask);
|
reg_esp|=(reg_ebp&cpu.stack.mask);
|
||||||
@ -741,57 +713,54 @@
|
|||||||
CASE_W(0xca) /* RETF Iw */
|
CASE_W(0xca) /* RETF Iw */
|
||||||
{
|
{
|
||||||
Bitu words=Fetchw();
|
Bitu words=Fetchw();
|
||||||
LEAVECORE;
|
FillFlags();
|
||||||
CPU_RET(false,words,core.ip_lookup-core.op_start);
|
CPU_RET(false,words,GETIP);
|
||||||
goto decode_start;
|
continue;
|
||||||
}
|
}
|
||||||
CASE_W(0xcb) /* RETF */
|
CASE_W(0xcb) /* RETF */
|
||||||
LEAVECORE;
|
FillFlags();
|
||||||
CPU_RET(false,0,core.ip_lookup-core.op_start);
|
CPU_RET(false,0,GETIP);
|
||||||
goto decode_start;
|
continue;
|
||||||
CASE_B(0xcc) /* INT3 */
|
CASE_B(0xcc) /* INT3 */
|
||||||
LEAVECORE;
|
FillFlags();
|
||||||
#if C_DEBUG
|
#if C_DEBUG
|
||||||
if (DEBUG_Breakpoint()) {
|
if (DEBUG_Breakpoint())
|
||||||
return debugCallback;
|
return debugCallback;
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
CPU_SW_Interrupt(3,(core.ip_lookup-core.op_start));
|
CPU_SW_Interrupt(3,GETIP);
|
||||||
#if CPU_TRAP_CHECK
|
#if CPU_TRAP_CHECK
|
||||||
core.trap.skip=true;
|
core.trap.skip=true;
|
||||||
#endif
|
#endif
|
||||||
goto decode_start;
|
continue;
|
||||||
CASE_B(0xcd) /* INT Ib */
|
CASE_B(0xcd) /* INT Ib */
|
||||||
{
|
{
|
||||||
Bit8u num=Fetchb();
|
Bit8u num=Fetchb();
|
||||||
LEAVECORE;
|
FillFlags();
|
||||||
#if C_DEBUG
|
#if C_DEBUG
|
||||||
if (DEBUG_IntBreakpoint(num)) {
|
if (DEBUG_IntBreakpoint(num)) {
|
||||||
return debugCallback;
|
return debugCallback;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
CPU_SW_Interrupt(num,core.ip_lookup-core.op_start);
|
CPU_SW_Interrupt(num,GETIP);
|
||||||
#if CPU_TRAP_CHECK
|
#if CPU_TRAP_CHECK
|
||||||
core.trap.skip=true;
|
core.trap.skip=true;
|
||||||
#endif
|
#endif
|
||||||
goto decode_start;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
CASE_B(0xce) /* INTO */
|
CASE_B(0xce) /* INTO */
|
||||||
if (get_OF()) {
|
if (get_OF()) {
|
||||||
LEAVECORE;
|
FillFlags();
|
||||||
CPU_SW_Interrupt(4,core.ip_lookup-core.op_start);
|
CPU_SW_Interrupt(4,GETIP);
|
||||||
#if CPU_TRAP_CHECK
|
#if CPU_TRAP_CHECK
|
||||||
core.trap.skip=true;
|
core.trap.skip=true;
|
||||||
#endif
|
#endif
|
||||||
goto decode_start;
|
continue;
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
CASE_W(0xcf) /* IRET */
|
CASE_W(0xcf) /* IRET */
|
||||||
{
|
{
|
||||||
LEAVECORE;
|
FillFlags();
|
||||||
CPU_IRET(false);
|
CPU_IRET(false,GETIP);
|
||||||
#if CPU_PIC_CHECK
|
#if CPU_PIC_CHECK
|
||||||
if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE;
|
if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE;
|
||||||
#endif
|
#endif
|
||||||
@ -801,7 +770,7 @@
|
|||||||
return CBRET_NONE;
|
return CBRET_NONE;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
goto decode_start;
|
continue;
|
||||||
}
|
}
|
||||||
CASE_B(0xd0) /* GRP2 Eb,1 */
|
CASE_B(0xd0) /* GRP2 Eb,1 */
|
||||||
GRP2B(1);break;
|
GRP2B(1);break;
|
||||||
@ -819,18 +788,10 @@
|
|||||||
reg_al = get_CF() ? 0xFF : 0;
|
reg_al = get_CF() ? 0xFF : 0;
|
||||||
break;
|
break;
|
||||||
CASE_B(0xd7) /* XLAT */
|
CASE_B(0xd7) /* XLAT */
|
||||||
if (TEST_PREFIX_SEG) {
|
|
||||||
if (TEST_PREFIX_ADDR) {
|
if (TEST_PREFIX_ADDR) {
|
||||||
reg_al=LoadMb(core.seg_prefix_base+(Bit32u)(reg_ebx+reg_al));
|
reg_al=LoadMb(BaseDS+(Bit32u)(reg_ebx+reg_al));
|
||||||
} else {
|
} else {
|
||||||
reg_al=LoadMb(core.seg_prefix_base+(Bit16u)(reg_bx+reg_al));
|
reg_al=LoadMb(BaseDS+(Bit16u)(reg_bx+reg_al));
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (TEST_PREFIX_ADDR) {
|
|
||||||
reg_al=LoadMb(SegBase(ds)+(Bit32u)(reg_ebx+reg_al));
|
|
||||||
} else {
|
|
||||||
reg_al=LoadMb(SegBase(ds)+(Bit16u)(reg_bx+reg_al));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#ifdef CPU_FPU
|
#ifdef CPU_FPU
|
||||||
@ -866,84 +827,104 @@
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
CASE_B(0xe0) /* LOOPNZ */
|
CASE_W(0xe0) /* LOOPNZ */
|
||||||
if (TEST_PREFIX_ADDR) {
|
if (TEST_PREFIX_ADDR) {
|
||||||
if ((--reg_ecx) && !get_ZF()) ADDIPFAST(Fetchbs());
|
JumpCond16_b(--reg_ecx && !get_ZF());
|
||||||
else ADDIPFAST(1);
|
|
||||||
} else {
|
} else {
|
||||||
if ((--reg_cx) && !get_ZF()) ADDIPFAST(Fetchbs());
|
JumpCond16_b(--reg_cx && !get_ZF());
|
||||||
else ADDIPFAST(1);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
CASE_B(0xe1) /* LOOPZ */
|
CASE_W(0xe1) /* LOOPZ */
|
||||||
if (TEST_PREFIX_ADDR) {
|
if (TEST_PREFIX_ADDR) {
|
||||||
if ((--reg_ecx) && get_ZF()) ADDIPFAST(Fetchbs());
|
JumpCond16_b(--reg_ecx && get_ZF());
|
||||||
else ADDIPFAST(1);
|
|
||||||
} else {
|
} else {
|
||||||
if ((--reg_cx) && get_ZF()) ADDIPFAST(Fetchbs());
|
JumpCond16_b(--reg_cx && get_ZF());
|
||||||
else ADDIPFAST(1);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
CASE_B(0xe2) /* LOOP */
|
CASE_W(0xe2) /* LOOP */
|
||||||
if (TEST_PREFIX_ADDR) {
|
if (TEST_PREFIX_ADDR) {
|
||||||
if ((--reg_ecx)) ADDIPFAST(Fetchbs());
|
JumpCond16_b(--reg_ecx);
|
||||||
else ADDIPFAST(1);
|
|
||||||
} else {
|
} else {
|
||||||
if ((--reg_cx)) ADDIPFAST(Fetchbs());
|
JumpCond16_b(--reg_cx);
|
||||||
else ADDIPFAST(1);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
CASE_B(0xe3) /* JCXZ */
|
CASE_W(0xe3) /* JCXZ */
|
||||||
{
|
JumpCond16_b(!(reg_ecx & AddrMaskTable[core.prefixes& PREFIX_ADDR]));
|
||||||
Bitu test;
|
|
||||||
if (TEST_PREFIX_ADDR) {
|
|
||||||
test=reg_ecx;
|
|
||||||
} else test=reg_cx;
|
|
||||||
if (!test) ADDIPFAST(Fetchbs());
|
|
||||||
else ADDIPFAST(1);
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
CASE_B(0xe4) /* IN AL,Ib */
|
CASE_B(0xe4) /* IN AL,Ib */
|
||||||
reg_al=IO_ReadB(Fetchb());
|
{
|
||||||
|
Bitu port=Fetchb();
|
||||||
|
if (CPU_IO_Exception(port,1)) RUNEXCEPTION();
|
||||||
|
reg_al=IO_ReadB(port);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
CASE_W(0xe5) /* IN AX,Ib */
|
CASE_W(0xe5) /* IN AX,Ib */
|
||||||
reg_ax=IO_ReadW(Fetchb());
|
{
|
||||||
|
Bitu port=Fetchb();
|
||||||
|
if (CPU_IO_Exception(port,2)) RUNEXCEPTION();
|
||||||
|
reg_al=IO_ReadW(port);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
CASE_B(0xe6) /* OUT Ib,AL */
|
CASE_B(0xe6) /* OUT Ib,AL */
|
||||||
IO_WriteB(Fetchb(),reg_al);
|
{
|
||||||
|
Bitu port=Fetchb();
|
||||||
|
if (CPU_IO_Exception(port,1)) RUNEXCEPTION();
|
||||||
|
IO_WriteB(port,reg_al);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
CASE_W(0xe7) /* OUT Ib,AX */
|
CASE_W(0xe7) /* OUT Ib,AX */
|
||||||
IO_WriteW(Fetchb(),reg_ax);
|
{
|
||||||
|
Bitu port=Fetchb();
|
||||||
|
if (CPU_IO_Exception(port,2)) RUNEXCEPTION();
|
||||||
|
IO_WriteW(port,reg_ax);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
CASE_W(0xe8) /* CALL Jw */
|
CASE_W(0xe8) /* CALL Jw */
|
||||||
{
|
{
|
||||||
Bit16s newip=Fetchws();
|
Bit16u addip=Fetchws();
|
||||||
Push_16((Bit16u)GETIP);
|
SAVEIP;
|
||||||
ADDIPw(newip);
|
Push_16(reg_eip);
|
||||||
break;
|
reg_eip=(Bit16u)(reg_eip+addip);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
CASE_W(0xe9) /* JMP Jw */
|
CASE_W(0xe9) /* JMP Jw */
|
||||||
ADDIPw(Fetchws());
|
{
|
||||||
break;
|
Bit16u addip=Fetchws();
|
||||||
|
SAVEIP;
|
||||||
|
reg_eip=(Bit16u)(reg_eip+addip);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
CASE_W(0xea) /* JMP Ap */
|
CASE_W(0xea) /* JMP Ap */
|
||||||
{
|
{
|
||||||
Bit16u newip=Fetchw();
|
Bit16u newip=Fetchw();
|
||||||
Bit16u newcs=Fetchw();
|
Bit16u newcs=Fetchw();
|
||||||
LEAVECORE;
|
FillFlags();
|
||||||
CPU_JMP(false,newcs,newip,core.ip_lookup-core.op_start);
|
CPU_JMP(false,newcs,newip,GETIP);
|
||||||
goto decode_start;
|
continue;
|
||||||
|
}
|
||||||
|
CASE_W(0xeb) /* JMP Jb */
|
||||||
|
{
|
||||||
|
Bit16s addip=Fetchbs();
|
||||||
|
SAVEIP;
|
||||||
|
reg_eip=(Bit16u)(reg_eip+addip);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
CASE_B(0xeb) /* JMP Jb */
|
|
||||||
ADDIPFAST(Fetchbs());break;
|
|
||||||
CASE_B(0xec) /* IN AL,DX */
|
CASE_B(0xec) /* IN AL,DX */
|
||||||
reg_al=IO_Read(reg_dx);break;
|
if (CPU_IO_Exception(reg_dx,1)) RUNEXCEPTION();
|
||||||
|
reg_al=IO_ReadB(reg_dx);
|
||||||
|
break;
|
||||||
CASE_W(0xed) /* IN AX,DX */
|
CASE_W(0xed) /* IN AX,DX */
|
||||||
reg_al=IO_Read(reg_dx);reg_ah=IO_Read(reg_dx+1);
|
if (CPU_IO_Exception(reg_dx,2)) RUNEXCEPTION();
|
||||||
|
reg_ax=IO_ReadW(reg_dx);
|
||||||
break;
|
break;
|
||||||
CASE_B(0xee) /* OUT DX,AL */
|
CASE_B(0xee) /* OUT DX,AL */
|
||||||
IO_WriteB(reg_dx,reg_al);break;
|
if (CPU_IO_Exception(reg_dx,1)) RUNEXCEPTION();
|
||||||
|
IO_WriteB(reg_dx,reg_al);
|
||||||
|
break;
|
||||||
CASE_W(0xef) /* OUT DX,AX */
|
CASE_W(0xef) /* OUT DX,AX */
|
||||||
IO_WriteW(reg_dx,reg_ax);break;
|
if (CPU_IO_Exception(reg_dx,2)) RUNEXCEPTION();
|
||||||
|
IO_WriteW(reg_dx,reg_ax);
|
||||||
|
break;
|
||||||
CASE_B(0xf0) /* LOCK */
|
CASE_B(0xf0) /* LOCK */
|
||||||
LOG(LOG_CPU,LOG_NORMAL)("CPU:LOCK");
|
LOG(LOG_CPU,LOG_NORMAL)("CPU:LOCK");
|
||||||
break;
|
break;
|
||||||
@ -954,8 +935,8 @@
|
|||||||
DO_PREFIX_REP(true);
|
DO_PREFIX_REP(true);
|
||||||
break;
|
break;
|
||||||
CASE_B(0xf4) /* HLT */
|
CASE_B(0xf4) /* HLT */
|
||||||
LEAVECORE;
|
FillFlags();
|
||||||
CPU_HLT(core.ip_lookup-core.op_start);
|
CPU_HLT(GETIP);
|
||||||
return CBRET_NONE; //Needs to return for hlt cpu core
|
return CBRET_NONE; //Needs to return for hlt cpu core
|
||||||
CASE_B(0xf5) /* CMC */
|
CASE_B(0xf5) /* CMC */
|
||||||
FillFlags();
|
FillFlags();
|
||||||
@ -1058,20 +1039,10 @@
|
|||||||
SETFLAGBIT(CF,true);
|
SETFLAGBIT(CF,true);
|
||||||
break;
|
break;
|
||||||
CASE_B(0xfa) /* CLI */
|
CASE_B(0xfa) /* CLI */
|
||||||
if (cpu.pmode && (GETFLAG_IOPL<cpu.cpl)) {
|
if (CPU_CLI()) RUNEXCEPTION();
|
||||||
LEAVECORE;reg_eip-=core.ip_lookup-core.op_start;
|
|
||||||
CPU_Exception(13,0);
|
|
||||||
goto decode_start;
|
|
||||||
}
|
|
||||||
SETFLAGBIT(IF,false);
|
|
||||||
break;
|
break;
|
||||||
CASE_B(0xfb) /* STI */
|
CASE_B(0xfb) /* STI */
|
||||||
if (cpu.pmode && !GETFLAG(VM) && (GETFLAG_IOPL<cpu.cpl)) {
|
if (CPU_STI()) RUNEXCEPTION();
|
||||||
LEAVECORE;reg_eip-=core.ip_lookup-core.op_start;
|
|
||||||
CPU_Exception(13,0);
|
|
||||||
goto decode_start;
|
|
||||||
}
|
|
||||||
SETFLAGBIT(IF,true);
|
|
||||||
#if CPU_PIC_CHECK
|
#if CPU_PIC_CHECK
|
||||||
if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end;
|
if (GETFLAG(IF) && PIC_IRQCheck) goto decode_end;
|
||||||
#endif
|
#endif
|
||||||
@ -1097,7 +1068,7 @@
|
|||||||
case 0x07: /* CallBack */
|
case 0x07: /* CallBack */
|
||||||
{
|
{
|
||||||
Bitu cb=Fetchw();
|
Bitu cb=Fetchw();
|
||||||
LEAVECORE;
|
FillFlags();SAVEIP;
|
||||||
return cb;
|
return cb;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -1117,31 +1088,32 @@
|
|||||||
RMEw(DECW);
|
RMEw(DECW);
|
||||||
break;
|
break;
|
||||||
case 0x02: /* CALL Ev */
|
case 0x02: /* CALL Ev */
|
||||||
if (rm >= 0xc0 ) {GetEArw;Push_16((Bit16u)GETIP);SETIP(*earw);}
|
if (rm >= 0xc0 ) {GetEArw;reg_eip=*earw;}
|
||||||
else {GetEAa;Push_16((Bit16u)GETIP);SETIP(LoadMw(eaa));}
|
else {GetEAa;reg_eip=LoadMw(eaa);}
|
||||||
break;
|
Push_16(GETIP);
|
||||||
|
continue;
|
||||||
case 0x03: /* CALL Ep */
|
case 0x03: /* CALL Ep */
|
||||||
{
|
{
|
||||||
GetEAa;
|
GetEAa;
|
||||||
Bit16u newip=LoadMw(eaa);
|
Bit16u newip=LoadMw(eaa);
|
||||||
Bit16u newcs=LoadMw(eaa+2);
|
Bit16u newcs=LoadMw(eaa+2);
|
||||||
LEAVECORE;
|
FillFlags();
|
||||||
CPU_CALL(false,newcs,newip,core.ip_lookup-core.op_start);
|
CPU_CALL(false,newcs,newip,GETIP);
|
||||||
goto decode_start;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x04: /* JMP Ev */
|
case 0x04: /* JMP Ev */
|
||||||
if (rm >= 0xc0 ) {GetEArw;SETIP(*earw);}
|
if (rm >= 0xc0 ) {GetEArw;reg_eip=*earw;}
|
||||||
else {GetEAa;SETIP(LoadMw(eaa));}
|
else {GetEAa;reg_eip=LoadMw(eaa);}
|
||||||
break;
|
continue;
|
||||||
case 0x05: /* JMP Ep */
|
case 0x05: /* JMP Ep */
|
||||||
{
|
{
|
||||||
GetEAa;
|
GetEAa;
|
||||||
Bit16u newip=LoadMw(eaa);
|
Bit16u newip=LoadMw(eaa);
|
||||||
Bit16u newcs=LoadMw(eaa+2);
|
Bit16u newcs=LoadMw(eaa+2);
|
||||||
LEAVECORE;
|
FillFlags();
|
||||||
CPU_JMP(false,newcs,newip,core.ip_lookup-core.op_start);
|
CPU_JMP(false,newcs,newip,GETIP);
|
||||||
goto decode_start;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x06: /* PUSH Ev */
|
case 0x06: /* PUSH Ev */
|
||||||
|
@ -17,21 +17,13 @@ static void DoString(STRING_OP type) {
|
|||||||
Bitu count,count_left;
|
Bitu count,count_left;
|
||||||
Bits add_index;
|
Bits add_index;
|
||||||
|
|
||||||
if (TEST_PREFIX_SEG) si_base=core.seg_prefix_base;
|
si_base=BaseDS;
|
||||||
else si_base=SegBase(ds);
|
|
||||||
di_base=SegBase(es);
|
di_base=SegBase(es);
|
||||||
if (TEST_PREFIX_ADDR) {
|
add_mask=AddrMaskTable[core.prefixes & PREFIX_ADDR];
|
||||||
add_mask=0xFFFFFFFF;
|
si_index=reg_esi & add_mask;
|
||||||
si_index=reg_esi;
|
di_index=reg_edi & add_mask;
|
||||||
di_index=reg_edi;
|
count=reg_ecx & add_mask;
|
||||||
count=reg_ecx;
|
if (!TEST_PREFIX_REP) {
|
||||||
} else {
|
|
||||||
add_mask=0xFFFF;
|
|
||||||
si_index=reg_si;
|
|
||||||
di_index=reg_di;
|
|
||||||
count=reg_cx;
|
|
||||||
}
|
|
||||||
if (!(TEST_PREFIX_REP)) {
|
|
||||||
count=1;
|
count=1;
|
||||||
} else {
|
} else {
|
||||||
CPU_Cycles++;
|
CPU_Cycles++;
|
||||||
@ -40,7 +32,7 @@ static void DoString(STRING_OP type) {
|
|||||||
count_left=count-CPU_Cycles;
|
count_left=count-CPU_Cycles;
|
||||||
count=CPU_Cycles;
|
count=CPU_Cycles;
|
||||||
CPU_Cycles=0;
|
CPU_Cycles=0;
|
||||||
core.ip_lookup=core.op_start; //Reset IP to start of instruction
|
LOADIP; //RESET IP to the start
|
||||||
} else {
|
} else {
|
||||||
/* Won't interrupt scas and cmps instruction since they can interrupt themselves */
|
/* Won't interrupt scas and cmps instruction since they can interrupt themselves */
|
||||||
count_left=0;
|
count_left=0;
|
||||||
|
@ -9,66 +9,25 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define SETIP(_a_) (core.ip_lookup=SegBase(cs)+_a_)
|
|
||||||
#define GETIP (Bit32u)(core.ip_lookup-SegBase(cs))
|
|
||||||
#define SAVEIP {reg_eip=GETIP;}
|
|
||||||
#define LOADIP {core.ip_lookup=(SegBase(cs)+reg_eip);}
|
|
||||||
|
|
||||||
#define LEAVECORE \
|
#define LoadMbs(off) (Bit8s)(LoadMb(off))
|
||||||
SAVEIP; \
|
#define LoadMws(off) (Bit16s)(LoadMw(off))
|
||||||
FillFlags();
|
#define LoadMds(off) (Bit32s)(LoadMd(off))
|
||||||
|
|
||||||
static INLINE void ADDIPw(Bits add) {
|
#define LoadRb(reg) reg
|
||||||
SAVEIP;
|
#define LoadRw(reg) reg
|
||||||
reg_eip=(Bit16u)(reg_eip+add);
|
#define LoadRd(reg) reg
|
||||||
LOADIP;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void ADDIPd(Bits add) {
|
#define SaveRb(reg,val) reg=val
|
||||||
SAVEIP;
|
#define SaveRw(reg,val) reg=val
|
||||||
reg_eip=(reg_eip+add);
|
#define SaveRd(reg,val) reg=val
|
||||||
LOADIP;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void ADDIPFAST(Bits blah) {
|
|
||||||
// core.ip_lookup+=blah;
|
|
||||||
SAVEIP;
|
|
||||||
reg_eip=(reg_eip+blah);
|
|
||||||
LOADIP;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define EXCEPTION(blah) \
|
|
||||||
{ \
|
|
||||||
Bit8u new_num=blah; \
|
|
||||||
core.ip_lookup=core.op_start; \
|
|
||||||
LEAVECORE; \
|
|
||||||
CPU_Exception(new_num); \
|
|
||||||
goto decode_start; \
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE Bit8u Fetchb() {
|
|
||||||
Bit8u temp=LoadMb(core.ip_lookup);
|
|
||||||
core.ip_lookup+=1;
|
|
||||||
return temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE Bit16u Fetchw() {
|
|
||||||
Bit16u temp=LoadMw(core.ip_lookup);
|
|
||||||
core.ip_lookup+=2;
|
|
||||||
return temp;
|
|
||||||
}
|
|
||||||
static INLINE Bit32u Fetchd() {
|
|
||||||
Bit32u temp=LoadMd(core.ip_lookup);
|
|
||||||
core.ip_lookup+=4;
|
|
||||||
return temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE Bit8s Fetchbs() {
|
static INLINE Bit8s Fetchbs() {
|
||||||
return Fetchb();
|
return Fetchb();
|
||||||
@ -81,68 +40,48 @@ static INLINE Bit32s Fetchds() {
|
|||||||
return Fetchd();
|
return Fetchd();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
static INLINE void Push_16(Bit16u blah) {
|
#define RUNEXCEPTION() { \
|
||||||
reg_esp-=2;
|
FillFlags(); \
|
||||||
SaveMw(SegBase(ss)+(reg_esp & cpu.stack.mask),blah);
|
CPU_Exception(cpu.exception.which,cpu.exception.error); \
|
||||||
};
|
continue; \
|
||||||
|
}
|
||||||
|
|
||||||
static INLINE void Push_32(Bit32u blah) {
|
#define EXCEPTION(blah) \
|
||||||
reg_esp-=4;
|
{ \
|
||||||
SaveMd(SegBase(ss)+(reg_esp & cpu.stack.mask),blah);
|
CPU_Exception(blah); \
|
||||||
};
|
continue; \
|
||||||
|
}
|
||||||
static INLINE Bit16u Pop_16() {
|
|
||||||
Bit16u temp=LoadMw(SegBase(ss)+(reg_esp & cpu.stack.mask));
|
|
||||||
reg_esp+=2;
|
|
||||||
return temp;
|
|
||||||
};
|
|
||||||
|
|
||||||
static INLINE Bit32u Pop_32() {
|
|
||||||
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
|
|
||||||
|
|
||||||
//TODO Could probably make all byte operands fast?
|
//TODO Could probably make all byte operands fast?
|
||||||
#define JumpCond16_b(blah) \
|
#define JumpCond16_b(COND) { \
|
||||||
if (blah) { \
|
SAVEIP; \
|
||||||
ADDIPw(Fetchbs()); \
|
if (COND) reg_ip+=Fetchbs(); \
|
||||||
} else { \
|
reg_ip+=1; \
|
||||||
ADDIPFAST(1); \
|
continue; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define JumpCond32_b(blah) \
|
#define JumpCond16_w(COND) { \
|
||||||
if (blah) { \
|
SAVEIP; \
|
||||||
ADDIPd(Fetchbs()); \
|
if (COND) reg_ip+=Fetchws(); \
|
||||||
} else { \
|
reg_ip+=2; \
|
||||||
ADDIPFAST(1); \
|
continue; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define JumpCond16_w(blah) \
|
#define JumpCond32_b(COND) { \
|
||||||
if (blah) { \
|
SAVEIP; \
|
||||||
ADDIPw(Fetchws()); \
|
if (COND) reg_eip+=Fetchbs(); \
|
||||||
} else { \
|
reg_eip+=1; \
|
||||||
ADDIPFAST(2); \
|
continue; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define JumpCond32_d(COND) { \
|
||||||
|
SAVEIP; \
|
||||||
|
if (COND) reg_eip+=Fetchds(); \
|
||||||
|
reg_eip+=4; \
|
||||||
|
continue; \
|
||||||
|
}
|
||||||
|
|
||||||
#define JumpCond32_d(blah) \
|
|
||||||
if (blah) { \
|
|
||||||
ADDIPd(Fetchds()); \
|
|
||||||
} else { \
|
|
||||||
ADDIPFAST(4); \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SETcc(cc) \
|
#define SETcc(cc) \
|
||||||
{ \
|
{ \
|
||||||
|
@ -9,327 +9,164 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef PhysPt (*GetEATable[256])(void);
|
|
||||||
typedef PhysPt (*EA_LookupHandler)(void);
|
typedef PhysPt (*EA_LookupHandler)(void);
|
||||||
|
|
||||||
|
|
||||||
/* The MOD/RM Decoder for EA for this decoder's addressing modes */
|
/* 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_00_n(void) { return BaseDS+(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_01_n(void) { return BaseDS+(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_02_n(void) { return BaseSS+(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_03_n(void) { return BaseSS+(Bit16u)(reg_bp+(Bit16s)reg_di); }
|
||||||
static PhysPt EA_16_04_n(void) { return SegBase(ds)+(Bit16u)(reg_si); }
|
static PhysPt EA_16_04_n(void) { return BaseDS+(Bit16u)(reg_si); }
|
||||||
static PhysPt EA_16_05_n(void) { return SegBase(ds)+(Bit16u)(reg_di); }
|
static PhysPt EA_16_05_n(void) { return BaseDS+(Bit16u)(reg_di); }
|
||||||
static PhysPt EA_16_06_n(void) { return SegBase(ds)+(Bit16u)(Fetchw());}
|
static PhysPt EA_16_06_n(void) { return BaseDS+(Bit16u)(Fetchw());}
|
||||||
static PhysPt EA_16_07_n(void) { return SegBase(ds)+(Bit16u)(reg_bx); }
|
static PhysPt EA_16_07_n(void) { return BaseDS+(Bit16u)(reg_bx); }
|
||||||
|
|
||||||
static PhysPt EA_16_40_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchbs()); }
|
static PhysPt EA_16_40_n(void) { return BaseDS+(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_41_n(void) { return BaseDS+(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_42_n(void) { return BaseSS+(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_43_n(void) { return BaseSS+(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_44_n(void) { return BaseDS+(Bit16u)(reg_si+Fetchbs()); }
|
||||||
static PhysPt EA_16_45_n(void) { return SegBase(ds)+(Bit16u)(reg_di+Fetchbs()); }
|
static PhysPt EA_16_45_n(void) { return BaseDS+(Bit16u)(reg_di+Fetchbs()); }
|
||||||
static PhysPt EA_16_46_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+Fetchbs()); }
|
static PhysPt EA_16_46_n(void) { return BaseSS+(Bit16u)(reg_bp+Fetchbs()); }
|
||||||
static PhysPt EA_16_47_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+Fetchbs()); }
|
static PhysPt EA_16_47_n(void) { return BaseDS+(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_80_n(void) { return BaseDS+(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_81_n(void) { return BaseDS+(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_82_n(void) { return BaseSS+(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_83_n(void) { return BaseSS+(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_84_n(void) { return BaseDS+(Bit16u)(reg_si+Fetchws()); }
|
||||||
static PhysPt EA_16_85_n(void) { return SegBase(ds)+(Bit16u)(reg_di+Fetchws()); }
|
static PhysPt EA_16_85_n(void) { return BaseDS+(Bit16u)(reg_di+Fetchws()); }
|
||||||
static PhysPt EA_16_86_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+Fetchws()); }
|
static PhysPt EA_16_86_n(void) { return BaseSS+(Bit16u)(reg_bp+Fetchws()); }
|
||||||
static PhysPt EA_16_87_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+Fetchws()); }
|
static PhysPt EA_16_87_n(void) { return BaseDS+(Bit16u)(reg_bx+Fetchws()); }
|
||||||
|
|
||||||
static GetEATable GetEA_NONE={
|
|
||||||
/* 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.seg_prefix_base+(Bit16u)(reg_bx+(Bit16s)reg_si); }
|
|
||||||
static PhysPt EA_16_01_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bx+(Bit16s)reg_di); }
|
|
||||||
static PhysPt EA_16_02_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bp+(Bit16s)reg_si); }
|
|
||||||
static PhysPt EA_16_03_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bp+(Bit16s)reg_di); }
|
|
||||||
static PhysPt EA_16_04_s(void) { return core.seg_prefix_base+(Bit16u)(reg_si); }
|
|
||||||
static PhysPt EA_16_05_s(void) { return core.seg_prefix_base+(Bit16u)(reg_di); }
|
|
||||||
static PhysPt EA_16_06_s(void) { return core.seg_prefix_base+(Bit16u)(Fetchw()); }
|
|
||||||
static PhysPt EA_16_07_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bx); }
|
|
||||||
|
|
||||||
static PhysPt EA_16_40_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchbs()); }
|
|
||||||
static PhysPt EA_16_41_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchbs()); }
|
|
||||||
static PhysPt EA_16_42_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchbs()); }
|
|
||||||
static PhysPt EA_16_43_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchbs()); }
|
|
||||||
static PhysPt EA_16_44_s(void) { return core.seg_prefix_base+(Bit16u)(reg_si+Fetchbs()); }
|
|
||||||
static PhysPt EA_16_45_s(void) { return core.seg_prefix_base+(Bit16u)(reg_di+Fetchbs()); }
|
|
||||||
static PhysPt EA_16_46_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bp+Fetchbs()); }
|
|
||||||
static PhysPt EA_16_47_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bx+Fetchbs()); }
|
|
||||||
|
|
||||||
static PhysPt EA_16_80_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchws()); }
|
|
||||||
static PhysPt EA_16_81_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchws()); }
|
|
||||||
static PhysPt EA_16_82_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchws()); }
|
|
||||||
static PhysPt EA_16_83_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchws()); }
|
|
||||||
static PhysPt EA_16_84_s(void) { return core.seg_prefix_base+(Bit16u)(reg_si+Fetchws()); }
|
|
||||||
static PhysPt EA_16_85_s(void) { return core.seg_prefix_base+(Bit16u)(reg_di+Fetchws()); }
|
|
||||||
static PhysPt EA_16_86_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bp+Fetchws()); }
|
|
||||||
static PhysPt EA_16_87_s(void) { return core.seg_prefix_base+(Bit16u)(reg_bx+Fetchws()); }
|
|
||||||
|
|
||||||
static GetEATable GetEA_SEG={
|
|
||||||
/* 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 SIBZero=0;
|
||||||
static Bit32u * SIBIndex[8]= { ®_eax,®_ecx,®_edx,®_ebx,&SIBZero,®_ebp,®_esi,®_edi };
|
static Bit32u * SIBIndex[8]= { ®_eax,®_ecx,®_edx,®_ebx,&SIBZero,®_ebp,®_esi,®_edi };
|
||||||
|
|
||||||
INLINE PhysPt Sib(Bitu mode) {
|
static INLINE PhysPt Sib(Bitu mode) {
|
||||||
Bit8u sib=Fetchb();
|
Bit8u sib=Fetchb();
|
||||||
PhysPt base;
|
PhysPt base;
|
||||||
switch (sib&7) {
|
switch (sib&7) {
|
||||||
case 0: /* EAX Base */
|
case 0: /* EAX Base */
|
||||||
base=SegBase(ds)+reg_eax;break;
|
base=BaseDS+reg_eax;break;
|
||||||
case 1: /* ECX Base */
|
case 1: /* ECX Base */
|
||||||
base=SegBase(ds)+reg_ecx;break;
|
base=BaseDS+reg_ecx;break;
|
||||||
case 2: /* EDX Base */
|
case 2: /* EDX Base */
|
||||||
base=SegBase(ds)+reg_edx;break;
|
base=BaseDS+reg_edx;break;
|
||||||
case 3: /* EBX Base */
|
case 3: /* EBX Base */
|
||||||
base=SegBase(ds)+reg_ebx;break;
|
base=BaseDS+reg_ebx;break;
|
||||||
case 4: /* ESP Base */
|
case 4: /* ESP Base */
|
||||||
base=SegBase(ss)+reg_esp;break;
|
base=BaseSS+reg_esp;break;
|
||||||
case 5: /* #1 Base */
|
case 5: /* #1 Base */
|
||||||
if (!mode) {
|
if (!mode) {
|
||||||
base=SegBase(ds)+Fetchd();break;
|
base=BaseDS+Fetchd();break;
|
||||||
} else {
|
} else {
|
||||||
base=SegBase(ss)+reg_ebp;break;
|
base=BaseSS+reg_ebp;break;
|
||||||
}
|
}
|
||||||
case 6: /* ESI Base */
|
case 6: /* ESI Base */
|
||||||
base=SegBase(ds)+reg_esi;break;
|
base=BaseDS+reg_esi;break;
|
||||||
case 7: /* EDI Base */
|
case 7: /* EDI Base */
|
||||||
base=SegBase(ds)+reg_edi;break;
|
base=BaseDS+reg_edi;break;
|
||||||
}
|
}
|
||||||
base+=*SIBIndex[(sib >> 3) &7] << (sib >> 6);
|
base+=*SIBIndex[(sib >> 3) &7] << (sib >> 6);
|
||||||
return base;
|
return base;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static PhysPt EA_32_00_n(void) { return BaseDS+reg_eax; }
|
||||||
static PhysPt EA_32_00_n(void) { return SegBase(ds)+reg_eax; }
|
static PhysPt EA_32_01_n(void) { return BaseDS+reg_ecx; }
|
||||||
static PhysPt EA_32_01_n(void) { return SegBase(ds)+reg_ecx; }
|
static PhysPt EA_32_02_n(void) { return BaseDS+reg_edx; }
|
||||||
static PhysPt EA_32_02_n(void) { return SegBase(ds)+reg_edx; }
|
static PhysPt EA_32_03_n(void) { return BaseDS+reg_ebx; }
|
||||||
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_04_n(void) { return Sib(0);}
|
||||||
static PhysPt EA_32_05_n(void) { return SegBase(ds)+Fetchd(); }
|
static PhysPt EA_32_05_n(void) { return BaseDS+Fetchd(); }
|
||||||
static PhysPt EA_32_06_n(void) { return SegBase(ds)+reg_esi; }
|
static PhysPt EA_32_06_n(void) { return BaseDS+reg_esi; }
|
||||||
static PhysPt EA_32_07_n(void) { return SegBase(ds)+reg_edi; }
|
static PhysPt EA_32_07_n(void) { return BaseDS+reg_edi; }
|
||||||
|
|
||||||
static PhysPt EA_32_40_n(void) { return SegBase(ds)+reg_eax+Fetchbs(); }
|
static PhysPt EA_32_40_n(void) { return BaseDS+reg_eax+Fetchbs(); }
|
||||||
static PhysPt EA_32_41_n(void) { return SegBase(ds)+reg_ecx+Fetchbs(); }
|
static PhysPt EA_32_41_n(void) { return BaseDS+reg_ecx+Fetchbs(); }
|
||||||
static PhysPt EA_32_42_n(void) { return SegBase(ds)+reg_edx+Fetchbs(); }
|
static PhysPt EA_32_42_n(void) { return BaseDS+reg_edx+Fetchbs(); }
|
||||||
static PhysPt EA_32_43_n(void) { return SegBase(ds)+reg_ebx+Fetchbs(); }
|
static PhysPt EA_32_43_n(void) { return BaseDS+reg_ebx+Fetchbs(); }
|
||||||
static PhysPt EA_32_44_n(void) { PhysPt temp=Sib(1);return temp+Fetchbs();}
|
static PhysPt EA_32_44_n(void) { PhysPt temp=Sib(1);return temp+Fetchbs();}
|
||||||
//static PhysPt EA_32_44_n(void) { return Sib(1)+Fetchbs();}
|
//static PhysPt EA_32_44_n(void) { return Sib(1)+Fetchbs();}
|
||||||
static PhysPt EA_32_45_n(void) { return SegBase(ss)+reg_ebp+Fetchbs(); }
|
static PhysPt EA_32_45_n(void) { return BaseSS+reg_ebp+Fetchbs(); }
|
||||||
static PhysPt EA_32_46_n(void) { return SegBase(ds)+reg_esi+Fetchbs(); }
|
static PhysPt EA_32_46_n(void) { return BaseDS+reg_esi+Fetchbs(); }
|
||||||
static PhysPt EA_32_47_n(void) { return SegBase(ds)+reg_edi+Fetchbs(); }
|
static PhysPt EA_32_47_n(void) { return BaseDS+reg_edi+Fetchbs(); }
|
||||||
|
|
||||||
static PhysPt EA_32_80_n(void) { return SegBase(ds)+reg_eax+Fetchds(); }
|
static PhysPt EA_32_80_n(void) { return BaseDS+reg_eax+Fetchds(); }
|
||||||
static PhysPt EA_32_81_n(void) { return SegBase(ds)+reg_ecx+Fetchds(); }
|
static PhysPt EA_32_81_n(void) { return BaseDS+reg_ecx+Fetchds(); }
|
||||||
static PhysPt EA_32_82_n(void) { return SegBase(ds)+reg_edx+Fetchds(); }
|
static PhysPt EA_32_82_n(void) { return BaseDS+reg_edx+Fetchds(); }
|
||||||
static PhysPt EA_32_83_n(void) { return SegBase(ds)+reg_ebx+Fetchds(); }
|
static PhysPt EA_32_83_n(void) { return BaseDS+reg_ebx+Fetchds(); }
|
||||||
static PhysPt EA_32_84_n(void) { PhysPt temp=Sib(2);return temp+Fetchds();}
|
static PhysPt EA_32_84_n(void) { PhysPt temp=Sib(2);return temp+Fetchds();}
|
||||||
//static PhysPt EA_32_84_n(void) { return Sib(2)+Fetchds();}
|
//static PhysPt EA_32_84_n(void) { return Sib(2)+Fetchds();}
|
||||||
static PhysPt EA_32_85_n(void) { return SegBase(ss)+reg_ebp+Fetchds(); }
|
static PhysPt EA_32_85_n(void) { return BaseSS+reg_ebp+Fetchds(); }
|
||||||
static PhysPt EA_32_86_n(void) { return SegBase(ds)+reg_esi+Fetchds(); }
|
static PhysPt EA_32_86_n(void) { return BaseDS+reg_esi+Fetchds(); }
|
||||||
static PhysPt EA_32_87_n(void) { return SegBase(ds)+reg_edi+Fetchds(); }
|
static PhysPt EA_32_87_n(void) { return BaseDS+reg_edi+Fetchds(); }
|
||||||
|
|
||||||
static GetEATable GetEA_ADDR={
|
static GetEAHandler EATable[512]={
|
||||||
/* 00 */
|
/* 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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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 */
|
/* 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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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 */
|
/* 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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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 */
|
/* 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,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 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.seg_prefix_base+(Bit32u)(reg_eax); }
|
|
||||||
static PhysPt EA_32_01_s(void) { return core.seg_prefix_base+(Bit32u)(reg_ecx); }
|
|
||||||
static PhysPt EA_32_02_s(void) { return core.seg_prefix_base+(Bit32u)(reg_edx); }
|
|
||||||
static PhysPt EA_32_03_s(void) { return core.seg_prefix_base+(Bit32u)(reg_ebx); }
|
|
||||||
static PhysPt EA_32_04_s(void) { return core.seg_prefix_base+(Bit32u)(Sib_s(0));}
|
|
||||||
static PhysPt EA_32_05_s(void) { return core.seg_prefix_base+(Bit32u)(Fetchd()); }
|
|
||||||
static PhysPt EA_32_06_s(void) { return core.seg_prefix_base+(Bit32u)(reg_esi); }
|
|
||||||
static PhysPt EA_32_07_s(void) { return core.seg_prefix_base+(Bit32u)(reg_edi); }
|
|
||||||
|
|
||||||
static PhysPt EA_32_40_s(void) { return core.seg_prefix_base+(Bit32u)(reg_eax+Fetchbs()); }
|
|
||||||
static PhysPt EA_32_41_s(void) { return core.seg_prefix_base+(Bit32u)(reg_ecx+Fetchbs()); }
|
|
||||||
static PhysPt EA_32_42_s(void) { return core.seg_prefix_base+(Bit32u)(reg_edx+Fetchbs()); }
|
|
||||||
static PhysPt EA_32_43_s(void) { return core.seg_prefix_base+(Bit32u)(reg_ebx+Fetchbs()); }
|
|
||||||
static PhysPt EA_32_44_s(void) { PhysPt temp=Sib_s(1);return core.seg_prefix_base+(Bit32u)(temp+Fetchbs());}
|
|
||||||
static PhysPt EA_32_45_s(void) { return core.seg_prefix_base+(Bit32u)(reg_ebp+Fetchbs()); }
|
|
||||||
static PhysPt EA_32_46_s(void) { return core.seg_prefix_base+(Bit32u)(reg_esi+Fetchbs()); }
|
|
||||||
static PhysPt EA_32_47_s(void) { return core.seg_prefix_base+(Bit32u)(reg_edi+Fetchbs()); }
|
|
||||||
|
|
||||||
static PhysPt EA_32_80_s(void) { return core.seg_prefix_base+(Bit32u)(reg_eax+Fetchds()); }
|
|
||||||
static PhysPt EA_32_81_s(void) { return core.seg_prefix_base+(Bit32u)(reg_ecx+Fetchds()); }
|
|
||||||
static PhysPt EA_32_82_s(void) { return core.seg_prefix_base+(Bit32u)(reg_edx+Fetchds()); }
|
|
||||||
static PhysPt EA_32_83_s(void) { return core.seg_prefix_base+(Bit32u)(reg_ebx+Fetchds()); }
|
|
||||||
static PhysPt EA_32_84_s(void) { PhysPt temp=Sib_s(2);return core.seg_prefix_base+(Bit32u)(temp+Fetchds());}
|
|
||||||
static PhysPt EA_32_85_s(void) { return core.seg_prefix_base+(Bit32u)(reg_ebp+Fetchds()); }
|
|
||||||
static PhysPt EA_32_86_s(void) { return core.seg_prefix_base+(Bit32u)(reg_esi+Fetchds()); }
|
|
||||||
static PhysPt EA_32_87_s(void) { return core.seg_prefix_base+(Bit32u)(reg_edi+Fetchds()); }
|
|
||||||
|
|
||||||
|
|
||||||
static GetEATable GetEA_SEG_ADDR={
|
|
||||||
/* 00 */
|
/* 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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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 */
|
/* 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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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 */
|
/* 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_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_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_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_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_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_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_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_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_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_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_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_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_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_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_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 */
|
/* 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,
|
||||||
@ -339,18 +176,10 @@ static GetEATable GetEA_SEG_ADDR={
|
|||||||
|
|
||||||
#define GetEADirect \
|
#define GetEADirect \
|
||||||
PhysPt eaa; \
|
PhysPt eaa; \
|
||||||
if (TEST_PREFIX_SEG) { \
|
|
||||||
if (TEST_PREFIX_ADDR) { \
|
if (TEST_PREFIX_ADDR) { \
|
||||||
eaa=core.seg_prefix_base+Fetchd(); \
|
eaa=BaseDS+Fetchd(); \
|
||||||
} else { \
|
} else { \
|
||||||
eaa=core.seg_prefix_base+Fetchw(); \
|
eaa=BaseDS+Fetchw(); \
|
||||||
} \
|
} \
|
||||||
} else { \
|
|
||||||
if (TEST_PREFIX_ADDR) { \
|
|
||||||
eaa=SegBase(ds)+Fetchd(); \
|
|
||||||
} else { \
|
|
||||||
eaa=SegBase(ds)+Fetchw(); \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
203
src/cpu/core_simple.cpp
Normal file
203
src/cpu/core_simple.cpp
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
/*
|
||||||
|
* 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 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 <stdio.h>
|
||||||
|
|
||||||
|
#include "dosbox.h"
|
||||||
|
#include "mem.h"
|
||||||
|
#include "cpu.h"
|
||||||
|
#include "lazyflags.h"
|
||||||
|
#include "inout.h"
|
||||||
|
#include "callback.h"
|
||||||
|
#include "pic.h"
|
||||||
|
#include "fpu.h"
|
||||||
|
|
||||||
|
#if C_DEBUG
|
||||||
|
#include "debug.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "paging.h"
|
||||||
|
#define SegBase(c) SegPhys(c)
|
||||||
|
#define LoadMb(off) mem_readb(off)
|
||||||
|
#define LoadMw(off) mem_readw(off)
|
||||||
|
#define LoadMd(off) mem_readd(off)
|
||||||
|
|
||||||
|
#define SaveMb(off,val) mem_writeb(off,val)
|
||||||
|
#define SaveMw(off,val) mem_writew(off,val)
|
||||||
|
#define SaveMd(off,val) mem_writed(off,val)
|
||||||
|
|
||||||
|
extern Bitu cycle_count;
|
||||||
|
|
||||||
|
#if C_FPU
|
||||||
|
#define CPU_FPU 1 //Enable FPU escape instructions
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CPU_PIC_CHECK 1
|
||||||
|
#define CPU_TRAP_CHECK 1
|
||||||
|
|
||||||
|
#define OPCODE_NONE 0x000
|
||||||
|
#define OPCODE_0F 0x100
|
||||||
|
#define OPCODE_SIZE 0x200
|
||||||
|
|
||||||
|
#define PREFIX_ADDR 0x1
|
||||||
|
#define PREFIX_REP 0x2
|
||||||
|
|
||||||
|
#define TEST_PREFIX_ADDR (core.prefixes & PREFIX_ADDR)
|
||||||
|
#define TEST_PREFIX_REP (core.prefixes & PREFIX_REP)
|
||||||
|
|
||||||
|
#define DO_PREFIX_SEG(_SEG) \
|
||||||
|
BaseDS=SegBase(_SEG); \
|
||||||
|
BaseSS=SegBase(_SEG); \
|
||||||
|
goto restart_opcode;
|
||||||
|
|
||||||
|
#define DO_PREFIX_ADDR() \
|
||||||
|
core.prefixes=(core.prefixes & ~PREFIX_ADDR) | \
|
||||||
|
(cpu.code.big ^ PREFIX_ADDR); \
|
||||||
|
core.ea_table=&EATable[(core.prefixes&1) * 256]; \
|
||||||
|
goto restart_opcode;
|
||||||
|
|
||||||
|
#define DO_PREFIX_REP(_ZERO) \
|
||||||
|
core.prefixes|=PREFIX_REP; \
|
||||||
|
core.rep_zero=_ZERO; \
|
||||||
|
goto restart_opcode;
|
||||||
|
|
||||||
|
typedef PhysPt (*GetEAHandler)(void);
|
||||||
|
|
||||||
|
static const Bit32u AddrMaskTable[2]={0x0000ffff,0xffffffff};
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
Bitu opcode_index;
|
||||||
|
HostPt cseip;
|
||||||
|
PhysPt base_ds,base_ss;
|
||||||
|
bool rep_zero;
|
||||||
|
Bitu prefixes;
|
||||||
|
GetEAHandler * ea_table;
|
||||||
|
struct {
|
||||||
|
bool skip;
|
||||||
|
} trap;
|
||||||
|
} core;
|
||||||
|
|
||||||
|
#define GETIP (core.cseip-SegBase(cs)-MemBase)
|
||||||
|
#define SAVEIP reg_eip=GETIP;
|
||||||
|
#define LOADIP core.cseip=(MemBase+SegBase(cs)+reg_eip);
|
||||||
|
|
||||||
|
#define SegBase(c) SegPhys(c)
|
||||||
|
#define BaseDS core.base_ds
|
||||||
|
#define BaseSS core.base_ss
|
||||||
|
|
||||||
|
static INLINE Bit8u Fetchb() {
|
||||||
|
Bit8u temp=host_readb(core.cseip);
|
||||||
|
core.cseip+=1;
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static INLINE Bit16u Fetchw() {
|
||||||
|
Bit16u temp=host_readw(core.cseip);
|
||||||
|
core.cseip+=2;
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
static INLINE Bit32u Fetchd() {
|
||||||
|
Bit32u temp=host_readd(core.cseip);
|
||||||
|
core.cseip+=4;
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define Push_16 CPU_Push16
|
||||||
|
#define Push_32 CPU_Push32
|
||||||
|
#define Pop_16 CPU_Pop16
|
||||||
|
#define Pop_32 CPU_Pop32
|
||||||
|
|
||||||
|
#include "instructions.h"
|
||||||
|
#include "core_normal/support.h"
|
||||||
|
#include "core_normal/string.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define EALookupTable (core.ea_table)
|
||||||
|
|
||||||
|
Bits CPU_Core_Simple_Run(void) {
|
||||||
|
while (CPU_Cycles-->0) {
|
||||||
|
LOADIP;
|
||||||
|
core.opcode_index=cpu.code.big*0x200;
|
||||||
|
core.prefixes=cpu.code.big;
|
||||||
|
core.ea_table=&EATable[cpu.code.big*256];
|
||||||
|
BaseDS=SegBase(ds);
|
||||||
|
BaseSS=SegBase(ss);
|
||||||
|
#if C_DEBUG
|
||||||
|
#if C_HEAVY_DEBUG
|
||||||
|
if (DEBUG_HeavyIsBreakpoint()) {
|
||||||
|
FillFlags();
|
||||||
|
return debugCallback;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
cycle_count++;
|
||||||
|
#endif
|
||||||
|
restart_opcode:
|
||||||
|
switch (core.opcode_index+Fetchb()) {
|
||||||
|
|
||||||
|
#include "core_normal/prefix_none.h"
|
||||||
|
#include "core_normal/prefix_0f.h"
|
||||||
|
#include "core_normal/prefix_66.h"
|
||||||
|
#include "core_normal/prefix_66_0f.h"
|
||||||
|
default:
|
||||||
|
illegal_opcode:
|
||||||
|
#if C_DEBUG
|
||||||
|
{
|
||||||
|
Bitu len=(GETIP-reg_eip);
|
||||||
|
LOADIP;
|
||||||
|
if (len>16) len=16;
|
||||||
|
char tempcode[16*2+1];char * writecode=tempcode;
|
||||||
|
for (;len>0;len--) {
|
||||||
|
// sprintf(writecode,"%X",mem_readb(core.cseip++));
|
||||||
|
writecode+=2;
|
||||||
|
}
|
||||||
|
LOG(LOG_CPU,LOG_ERROR)("Illegal/Unhandled opcode %s",tempcode);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
CPU_Exception(6,0);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
SAVEIP;
|
||||||
|
}
|
||||||
|
FillFlags();
|
||||||
|
return CBRET_NONE;
|
||||||
|
decode_end:
|
||||||
|
SAVEIP;
|
||||||
|
FillFlags();
|
||||||
|
return CBRET_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bits CPU_Core_Simple_Trap_Run(void) {
|
||||||
|
|
||||||
|
Bits oldCycles = CPU_Cycles;
|
||||||
|
CPU_Cycles = 1;
|
||||||
|
core.trap.skip=false;
|
||||||
|
|
||||||
|
Bits ret=CPU_Core_Normal_Run();
|
||||||
|
if (!core.trap.skip) CPU_SW_Interrupt(1,reg_eip);
|
||||||
|
CPU_Cycles = oldCycles-1;
|
||||||
|
cpudecoder = &CPU_Core_Normal_Run;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void CPU_Core_Simple_Init(void) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
264
src/cpu/cpu.cpp
264
src/cpu/cpu.cpp
@ -9,21 +9,21 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: cpu.cpp,v 1.53 2004/01/14 17:09:41 harekiet Exp $ */
|
/* $Id: cpu.cpp,v 1.61 2004/08/23 12:17:29 harekiet Exp $ */
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "dosbox.h"
|
#include "dosbox.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "keyboard.h"
|
#include "mapper.h"
|
||||||
#include "setup.h"
|
#include "setup.h"
|
||||||
#include "paging.h"
|
#include "paging.h"
|
||||||
#include "support.h"
|
#include "support.h"
|
||||||
@ -46,12 +46,9 @@ Bits CPU_CycleUp = 0;
|
|||||||
Bits CPU_CycleDown = 0;
|
Bits CPU_CycleDown = 0;
|
||||||
CPU_Decoder * cpudecoder;
|
CPU_Decoder * cpudecoder;
|
||||||
|
|
||||||
static struct {
|
|
||||||
Bitu which,errorcode;
|
|
||||||
} exception;
|
|
||||||
|
|
||||||
void CPU_Core_Full_Init(void);
|
void CPU_Core_Full_Init(void);
|
||||||
void CPU_Core_Normal_Init(void);
|
void CPU_Core_Normal_Init(void);
|
||||||
|
void CPU_Core_Simple_Init(void);
|
||||||
void CPU_Core_Dyn_X86_Init(void);
|
void CPU_Core_Dyn_X86_Init(void);
|
||||||
|
|
||||||
void CPU_Push16(Bitu value) {
|
void CPU_Push16(Bitu value) {
|
||||||
@ -91,6 +88,48 @@ void CPU_SetFlags(Bitu word,Bitu mask) {
|
|||||||
cpu.direction=1-((reg_flags & FLAG_DF) >> 9);
|
cpu.direction=1-((reg_flags & FLAG_DF) >> 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CPU_PrepareException(Bitu which,Bitu error) {
|
||||||
|
cpu.exception.which=which;
|
||||||
|
cpu.exception.error=error;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPU_CLI(void) {
|
||||||
|
if (cpu.pmode && ((!GETFLAG(VM) && (GETFLAG_IOPL<cpu.cpl)) || (GETFLAG(VM) && (GETFLAG_IOPL<3)))) {
|
||||||
|
return CPU_PrepareException(13,0);
|
||||||
|
} else {
|
||||||
|
SETFLAGBIT(IF,false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPU_STI(void) {
|
||||||
|
if (cpu.pmode && ((!GETFLAG(VM) && (GETFLAG_IOPL<cpu.cpl)) || (GETFLAG(VM) && (GETFLAG_IOPL<3)))) {
|
||||||
|
return CPU_PrepareException(13,0);
|
||||||
|
} else {
|
||||||
|
SETFLAGBIT(IF,true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPU_POPF(Bitu use32) {
|
||||||
|
if ((reg_flags & FLAG_VM) && (GETFLAG(IOPL)!=FLAG_IOPL))
|
||||||
|
return CPU_PrepareException(13,0);
|
||||||
|
if (use32)
|
||||||
|
CPU_SetFlagsd(CPU_Pop32());
|
||||||
|
else CPU_SetFlagsw(CPU_Pop16());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPU_PUSHF(Bitu use32) {
|
||||||
|
if ((reg_flags & FLAG_VM) && (GETFLAG(IOPL)!=FLAG_IOPL))
|
||||||
|
return CPU_PrepareException(13,0);
|
||||||
|
if (use32)
|
||||||
|
CPU_Push32(reg_flags);
|
||||||
|
else CPU_Push16(reg_flags);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
class TaskStateSegment {
|
class TaskStateSegment {
|
||||||
public:
|
public:
|
||||||
TaskStateSegment() {
|
TaskStateSegment() {
|
||||||
@ -148,7 +187,7 @@ enum TSwitchType {
|
|||||||
TSwitch_JMP,TSwitch_CALL_INT,TSwitch_IRET
|
TSwitch_JMP,TSwitch_CALL_INT,TSwitch_IRET
|
||||||
};
|
};
|
||||||
|
|
||||||
bool CPU_SwitchTask(Bitu new_tss_selector,TSwitchType tstype) {
|
bool CPU_SwitchTask(Bitu new_tss_selector,TSwitchType tstype,Bitu old_eip) {
|
||||||
TaskStateSegment new_tss;
|
TaskStateSegment new_tss;
|
||||||
if (!new_tss.SetSelector(new_tss_selector))
|
if (!new_tss.SetSelector(new_tss_selector))
|
||||||
E_Exit("Illegal TSS for switch");
|
E_Exit("Illegal TSS for switch");
|
||||||
@ -163,7 +202,7 @@ bool CPU_SwitchTask(Bitu new_tss_selector,TSwitchType tstype) {
|
|||||||
Bitu new_ldt;
|
Bitu new_ldt;
|
||||||
if (cpu_tss.is386) {
|
if (cpu_tss.is386) {
|
||||||
mem_writed(cpu_tss.base+offsetof(TSS_32,eflags),reg_flags);
|
mem_writed(cpu_tss.base+offsetof(TSS_32,eflags),reg_flags);
|
||||||
mem_writed(cpu_tss.base+offsetof(TSS_32,eip),reg_eip);
|
mem_writed(cpu_tss.base+offsetof(TSS_32,eip),old_eip);
|
||||||
|
|
||||||
mem_writed(cpu_tss.base+offsetof(TSS_32,eax),reg_eax);
|
mem_writed(cpu_tss.base+offsetof(TSS_32,eax),reg_eax);
|
||||||
mem_writed(cpu_tss.base+offsetof(TSS_32,ecx),reg_ecx);
|
mem_writed(cpu_tss.base+offsetof(TSS_32,ecx),reg_ecx);
|
||||||
@ -268,23 +307,31 @@ doconforming:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU_StartException(void) {
|
bool CPU_IO_Exception(Bitu port,Bitu size) {
|
||||||
CPU_Interrupt(cpu.exception.which,CPU_INT_EXCEPTION | ((cpu.exception.which>=8) ? CPU_INT_HAS_ERROR : 0));
|
if (cpu.pmode && ((GETFLAG_IOPL<cpu.cpl) || GETFLAG(VM))) {
|
||||||
}
|
if (!cpu_tss.is386) goto doexception;
|
||||||
|
PhysPt where=cpu_tss.base+0x66;
|
||||||
void CPU_SetupException(Bitu which,Bitu error) {
|
Bitu ofs=mem_readw(where);
|
||||||
cpu.exception.which=which;
|
if (ofs>cpu_tss.limit) goto doexception;
|
||||||
cpu.exception.error=error;
|
where=cpu_tss.base+ofs+(port/8);
|
||||||
|
Bitu map=mem_readw(where);
|
||||||
|
Bitu mask=(0xffff>>(16-size)) << (port&7);
|
||||||
|
if (map & mask) goto doexception;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
doexception:
|
||||||
|
LOG_MSG("Exception");
|
||||||
|
return CPU_PrepareException(13,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU_Exception(Bitu which,Bitu error ) {
|
void CPU_Exception(Bitu which,Bitu error ) {
|
||||||
// LOG_MSG("Exception %d CS:%X IP:%X FLAGS:%X",num,SegValue(cs),reg_eip,reg_flags);
|
// LOG_MSG("Exception %d error %x",which,error);
|
||||||
CPU_SetupException(which,error);
|
cpu.exception.error=error;
|
||||||
CPU_StartException();
|
CPU_Interrupt(which,CPU_INT_EXCEPTION | ((which>=8) ? CPU_INT_HAS_ERROR : 0),reg_eip);
|
||||||
}
|
}
|
||||||
|
|
||||||
Bit8u lastint;
|
Bit8u lastint;
|
||||||
void CPU_Interrupt(Bitu num,Bitu type,Bitu opLen) {
|
void CPU_Interrupt(Bitu num,Bitu type,Bitu oldeip) {
|
||||||
lastint=num;
|
lastint=num;
|
||||||
#if C_DEBUG
|
#if C_DEBUG
|
||||||
switch (num) {
|
switch (num) {
|
||||||
@ -305,7 +352,7 @@ void CPU_Interrupt(Bitu num,Bitu type,Bitu opLen) {
|
|||||||
/* Save everything on a 16-bit stack */
|
/* Save everything on a 16-bit stack */
|
||||||
CPU_Push16(reg_flags & 0xffff);
|
CPU_Push16(reg_flags & 0xffff);
|
||||||
CPU_Push16(SegValue(cs));
|
CPU_Push16(SegValue(cs));
|
||||||
CPU_Push16(reg_ip);
|
CPU_Push16(oldeip);
|
||||||
SETFLAGBIT(IF,false);
|
SETFLAGBIT(IF,false);
|
||||||
SETFLAGBIT(TF,false);
|
SETFLAGBIT(TF,false);
|
||||||
/* Get the new CS:IP from vector table */
|
/* Get the new CS:IP from vector table */
|
||||||
@ -323,7 +370,6 @@ void CPU_Interrupt(Bitu num,Bitu type,Bitu opLen) {
|
|||||||
if ((reg_flags & FLAG_VM) && (type&CPU_INT_SOFTWARE)) {
|
if ((reg_flags & FLAG_VM) && (type&CPU_INT_SOFTWARE)) {
|
||||||
// LOG_MSG("Software int in v86, AH %X IOPL %x",reg_ah,(reg_flags & FLAG_IOPL) >>12);
|
// LOG_MSG("Software int in v86, AH %X IOPL %x",reg_ah,(reg_flags & FLAG_IOPL) >>12);
|
||||||
if ((reg_flags & FLAG_IOPL)!=FLAG_IOPL) {
|
if ((reg_flags & FLAG_IOPL)!=FLAG_IOPL) {
|
||||||
reg_eip-=opLen;
|
|
||||||
CPU_Exception(13,0);
|
CPU_Exception(13,0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -332,7 +378,6 @@ void CPU_Interrupt(Bitu num,Bitu type,Bitu opLen) {
|
|||||||
//TODO Check for software interrupt and check gate's dpl<cpl
|
//TODO Check for software interrupt and check gate's dpl<cpl
|
||||||
cpu.idt.GetDescriptor(num<<3,gate);
|
cpu.idt.GetDescriptor(num<<3,gate);
|
||||||
if (type&CPU_INT_SOFTWARE && gate.DPL()<cpu.cpl) {
|
if (type&CPU_INT_SOFTWARE && gate.DPL()<cpu.cpl) {
|
||||||
reg_eip-=opLen;
|
|
||||||
CPU_Exception(13,num*8+2);
|
CPU_Exception(13,num*8+2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -397,12 +442,12 @@ do_interrupt:
|
|||||||
if (gate.Type() & 0x8) { /* 32-bit Gate */
|
if (gate.Type() & 0x8) { /* 32-bit Gate */
|
||||||
CPU_Push32(reg_flags);
|
CPU_Push32(reg_flags);
|
||||||
CPU_Push32(SegValue(cs));
|
CPU_Push32(SegValue(cs));
|
||||||
CPU_Push32(reg_eip);
|
CPU_Push32(oldeip);
|
||||||
if (type & CPU_INT_HAS_ERROR) CPU_Push32(cpu.exception.error);
|
if (type & CPU_INT_HAS_ERROR) CPU_Push32(cpu.exception.error);
|
||||||
} else { /* 16-bit gate */
|
} else { /* 16-bit gate */
|
||||||
CPU_Push16(reg_flags & 0xffff);
|
CPU_Push16(reg_flags & 0xffff);
|
||||||
CPU_Push16(SegValue(cs));
|
CPU_Push16(SegValue(cs));
|
||||||
CPU_Push16(reg_ip);
|
CPU_Push16(oldeip);
|
||||||
if (type & CPU_INT_HAS_ERROR) CPU_Push16(cpu.exception.error);
|
if (type & CPU_INT_HAS_ERROR) CPU_Push16(cpu.exception.error);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -422,7 +467,7 @@ do_interrupt:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case DESC_TASK_GATE:
|
case DESC_TASK_GATE:
|
||||||
CPU_SwitchTask(gate.GetSelector(),TSwitch_CALL_INT);
|
CPU_SwitchTask(gate.GetSelector(),TSwitch_CALL_INT,oldeip);
|
||||||
if (type & CPU_INT_HAS_ERROR) {
|
if (type & CPU_INT_HAS_ERROR) {
|
||||||
//TODO Be sure about this, seems somewhat unclear
|
//TODO Be sure about this, seems somewhat unclear
|
||||||
if (cpu_tss.is386) CPU_Push32(cpu.exception.error);
|
if (cpu_tss.is386) CPU_Push32(cpu.exception.error);
|
||||||
@ -437,7 +482,7 @@ do_interrupt:
|
|||||||
return ; // make compiler happy
|
return ; // make compiler happy
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU_IRET(bool use32) {
|
void CPU_IRET(bool use32,Bitu oldeip) {
|
||||||
if (!cpu.pmode) { /* RealMode IRET */
|
if (!cpu.pmode) { /* RealMode IRET */
|
||||||
realmode_iret:
|
realmode_iret:
|
||||||
if (use32) {
|
if (use32) {
|
||||||
@ -454,7 +499,6 @@ realmode_iret:
|
|||||||
} else { /* Protected mode IRET */
|
} else { /* Protected mode IRET */
|
||||||
if (reg_flags & FLAG_VM) {
|
if (reg_flags & FLAG_VM) {
|
||||||
if ((reg_flags & FLAG_IOPL)!=FLAG_IOPL) {
|
if ((reg_flags & FLAG_IOPL)!=FLAG_IOPL) {
|
||||||
reg_eip--;
|
|
||||||
CPU_Exception(13,0);
|
CPU_Exception(13,0);
|
||||||
return;
|
return;
|
||||||
} else goto realmode_iret;
|
} else goto realmode_iret;
|
||||||
@ -466,7 +510,7 @@ realmode_iret:
|
|||||||
if (GETFLAG(VM)) E_Exit("Pmode IRET with VM bit set");
|
if (GETFLAG(VM)) E_Exit("Pmode IRET with VM bit set");
|
||||||
if (!cpu_tss.IsValid()) E_Exit("TASK Iret without valid TSS");
|
if (!cpu_tss.IsValid()) E_Exit("TASK Iret without valid TSS");
|
||||||
Bitu back_link=cpu_tss.Get_back();
|
Bitu back_link=cpu_tss.Get_back();
|
||||||
CPU_SwitchTask(back_link,TSwitch_IRET);
|
CPU_SwitchTask(back_link,TSwitch_IRET,oldeip);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Bitu n_cs_sel,n_eip,n_flags;
|
Bitu n_cs_sel,n_eip,n_flags;
|
||||||
@ -526,6 +570,7 @@ realmode_iret:
|
|||||||
cpu.code.big=n_cs_desc.Big()>0;
|
cpu.code.big=n_cs_desc.Big()>0;
|
||||||
Segs.val[cs]=n_cs_sel;
|
Segs.val[cs]=n_cs_sel;
|
||||||
reg_eip=n_eip;
|
reg_eip=n_eip;
|
||||||
|
|
||||||
CPU_SetFlagsd(n_flags);
|
CPU_SetFlagsd(n_flags);
|
||||||
LOG(LOG_CPU,LOG_NORMAL)("IRET:Same level:%X:%X big %d",n_cs_sel,n_eip,cpu.code.big);
|
LOG(LOG_CPU,LOG_NORMAL)("IRET:Same level:%X:%X big %d",n_cs_sel,n_eip,cpu.code.big);
|
||||||
} else {
|
} else {
|
||||||
@ -545,9 +590,11 @@ realmode_iret:
|
|||||||
Segs.phys[cs]=n_cs_desc.GetBase();
|
Segs.phys[cs]=n_cs_desc.GetBase();
|
||||||
cpu.code.big=n_cs_desc.Big()>0;
|
cpu.code.big=n_cs_desc.Big()>0;
|
||||||
Segs.val[cs]=n_cs_sel;
|
Segs.val[cs]=n_cs_sel;
|
||||||
|
|
||||||
|
CPU_SetFlagsd(n_flags);
|
||||||
|
|
||||||
cpu.cpl=n_cs_rpl;
|
cpu.cpl=n_cs_rpl;
|
||||||
reg_eip=n_eip;
|
reg_eip=n_eip;
|
||||||
CPU_SetFlagsd(n_flags);
|
|
||||||
Bitu n_ss,n_esp;
|
Bitu n_ss,n_esp;
|
||||||
if (use32) {
|
if (use32) {
|
||||||
n_esp=CPU_Pop32();
|
n_esp=CPU_Pop32();
|
||||||
@ -562,14 +609,15 @@ realmode_iret:
|
|||||||
} else {
|
} else {
|
||||||
reg_sp=n_esp;
|
reg_sp=n_esp;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO Maybe validate other segments, but why would anyone use them?
|
//TODO Maybe validate other segments, but why would anyone use them?
|
||||||
LOG(LOG_CPU,LOG_NORMAL)("IRET:Outer level:%X:X big %d",n_cs_sel,n_eip,cpu.code.big);
|
LOG(LOG_CPU,LOG_NORMAL)("IRET:Outer level:%X:%X big %d",n_cs_sel,n_eip,cpu.code.big);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU_JMP(bool use32,Bitu selector,Bitu offset,Bitu opLen) {
|
void CPU_JMP(bool use32,Bitu selector,Bitu offset,Bitu oldeip) {
|
||||||
if (!cpu.pmode || (reg_flags & FLAG_VM)) {
|
if (!cpu.pmode || (reg_flags & FLAG_VM)) {
|
||||||
if (!use32) {
|
if (!use32) {
|
||||||
reg_eip=offset&0xffff;
|
reg_eip=offset&0xffff;
|
||||||
@ -584,7 +632,6 @@ void CPU_JMP(bool use32,Bitu selector,Bitu offset,Bitu opLen) {
|
|||||||
Descriptor desc;
|
Descriptor desc;
|
||||||
cpu.gdt.GetDescriptor(selector,desc);
|
cpu.gdt.GetDescriptor(selector,desc);
|
||||||
if (!desc.saved.seg.p) {
|
if (!desc.saved.seg.p) {
|
||||||
reg_eip -= opLen;
|
|
||||||
CPU_Exception(0x0B,selector & 0xfffc);
|
CPU_Exception(0x0B,selector & 0xfffc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -592,8 +639,7 @@ void CPU_JMP(bool use32,Bitu selector,Bitu offset,Bitu opLen) {
|
|||||||
case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA:
|
case DESC_CODE_N_NC_A: case DESC_CODE_N_NC_NA:
|
||||||
case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA:
|
case DESC_CODE_R_NC_A: case DESC_CODE_R_NC_NA:
|
||||||
if (rpl>cpu.cpl) E_Exit("JMP:NC:RPL>CPL");
|
if (rpl>cpu.cpl) E_Exit("JMP:NC:RPL>CPL");
|
||||||
if (rpl!=desc.DPL()) E_Exit("JMP:NC:RPL != DPL");
|
if (cpu.cpl!=desc.DPL()) E_Exit("JMP:NC:RPL != DPL");
|
||||||
cpu.cpl=desc.DPL();
|
|
||||||
LOG(LOG_CPU,LOG_NORMAL)("JMP:Code:NC to %X:%X big %d",selector,offset,desc.Big());
|
LOG(LOG_CPU,LOG_NORMAL)("JMP:Code:NC to %X:%X big %d",selector,offset,desc.Big());
|
||||||
goto CODE_jmp;
|
goto CODE_jmp;
|
||||||
case DESC_CODE_N_C_A: case DESC_CODE_N_C_NA:
|
case DESC_CODE_N_C_A: case DESC_CODE_N_C_NA:
|
||||||
@ -610,7 +656,7 @@ CODE_jmp:
|
|||||||
if (desc.DPL()<cpu.cpl) E_Exit("JMP:TSS:dpl<cpl");
|
if (desc.DPL()<cpu.cpl) E_Exit("JMP:TSS:dpl<cpl");
|
||||||
if (desc.DPL()<rpl) E_Exit("JMP:TSS:dpl<rpl");
|
if (desc.DPL()<rpl) E_Exit("JMP:TSS:dpl<rpl");
|
||||||
LOG(LOG_CPU,LOG_NORMAL)("JMP:TSS to %X",selector);
|
LOG(LOG_CPU,LOG_NORMAL)("JMP:TSS to %X",selector);
|
||||||
CPU_SwitchTask(selector,TSwitch_JMP);
|
CPU_SwitchTask(selector,TSwitch_JMP,oldeip);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
E_Exit("JMP Illegal descriptor type %X",desc.Type());
|
E_Exit("JMP Illegal descriptor type %X",desc.Type());
|
||||||
@ -621,15 +667,15 @@ CODE_jmp:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void CPU_CALL(bool use32,Bitu selector,Bitu offset,Bitu opLen) {
|
void CPU_CALL(bool use32,Bitu selector,Bitu offset,Bitu oldeip) {
|
||||||
if (!cpu.pmode || (reg_flags & FLAG_VM)) {
|
if (!cpu.pmode || (reg_flags & FLAG_VM)) {
|
||||||
if (!use32) {
|
if (!use32) {
|
||||||
CPU_Push16(SegValue(cs));
|
CPU_Push16(SegValue(cs));
|
||||||
CPU_Push16(reg_ip);
|
CPU_Push16(oldeip);
|
||||||
reg_eip=offset&0xffff;
|
reg_eip=offset&0xffff;
|
||||||
} else {
|
} else {
|
||||||
CPU_Push32(SegValue(cs));
|
CPU_Push32(SegValue(cs));
|
||||||
CPU_Push32(reg_eip);
|
CPU_Push32(oldeip);
|
||||||
reg_eip=offset;
|
reg_eip=offset;
|
||||||
}
|
}
|
||||||
cpu.code.big=false;
|
cpu.code.big=false;
|
||||||
@ -640,7 +686,6 @@ void CPU_CALL(bool use32,Bitu selector,Bitu offset,Bitu opLen) {
|
|||||||
Bitu rpl=selector & 3;
|
Bitu rpl=selector & 3;
|
||||||
cpu.gdt.GetDescriptor(selector,call);
|
cpu.gdt.GetDescriptor(selector,call);
|
||||||
if (!call.saved.seg.p) {
|
if (!call.saved.seg.p) {
|
||||||
reg_eip -= opLen;
|
|
||||||
CPU_Exception(0x0B,selector & 0xfffc);
|
CPU_Exception(0x0B,selector & 0xfffc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -659,11 +704,11 @@ void CPU_CALL(bool use32,Bitu selector,Bitu offset,Bitu opLen) {
|
|||||||
call_code:
|
call_code:
|
||||||
if (!use32) {
|
if (!use32) {
|
||||||
CPU_Push16(SegValue(cs));
|
CPU_Push16(SegValue(cs));
|
||||||
CPU_Push16(reg_ip);
|
CPU_Push16(oldeip);
|
||||||
reg_eip=offset & 0xffff;
|
reg_eip=offset & 0xffff;
|
||||||
} else {
|
} else {
|
||||||
CPU_Push32(SegValue(cs));
|
CPU_Push32(SegValue(cs));
|
||||||
CPU_Push32(reg_eip);
|
CPU_Push32(oldeip);
|
||||||
reg_eip=offset;
|
reg_eip=offset;
|
||||||
}
|
}
|
||||||
Segs.phys[cs]=call.GetBase();
|
Segs.phys[cs]=call.GetBase();
|
||||||
@ -679,7 +724,6 @@ call_code:
|
|||||||
Bitu n_cs_sel=call.GetSelector();
|
Bitu n_cs_sel=call.GetSelector();
|
||||||
if (!cpu.gdt.GetDescriptor(n_cs_sel,n_cs_desc)) E_Exit("Call:Gate:Invalid CS selector.");
|
if (!cpu.gdt.GetDescriptor(n_cs_sel,n_cs_desc)) E_Exit("Call:Gate:Invalid CS selector.");
|
||||||
if (!n_cs_desc.saved.seg.p) {
|
if (!n_cs_desc.saved.seg.p) {
|
||||||
reg_eip -= opLen;
|
|
||||||
CPU_Exception(0x0B,selector & 0xfffc);
|
CPU_Exception(0x0B,selector & 0xfffc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -709,19 +753,22 @@ call_code:
|
|||||||
if (call.Type()==DESC_386_CALL_GATE) {
|
if (call.Type()==DESC_386_CALL_GATE) {
|
||||||
CPU_Push32(o_ss); //save old stack
|
CPU_Push32(o_ss); //save old stack
|
||||||
CPU_Push32(o_esp);
|
CPU_Push32(o_esp);
|
||||||
for (Bitu i=0;i<(call.saved.gate.paramcount&31);i++)
|
if (call.saved.gate.paramcount&31)
|
||||||
|
for (Bits i=(call.saved.gate.paramcount&31)-1;i>=0;i--)
|
||||||
CPU_Push32(mem_readd(o_stack+i*4));
|
CPU_Push32(mem_readd(o_stack+i*4));
|
||||||
CPU_Push32(SegValue(cs));
|
CPU_Push32(SegValue(cs));
|
||||||
CPU_Push32(reg_eip);
|
CPU_Push32(oldeip);
|
||||||
} else {
|
} else {
|
||||||
CPU_Push16(o_ss); //save old stack
|
CPU_Push16(o_ss); //save old stack
|
||||||
CPU_Push16(o_esp);
|
CPU_Push16(o_esp);
|
||||||
for (Bitu i=0;i<(call.saved.gate.paramcount&31);i++)
|
if (call.saved.gate.paramcount&31)
|
||||||
|
for (Bits i=(call.saved.gate.paramcount&31)-1;i>=0;i--)
|
||||||
CPU_Push16(mem_readw(o_stack+i*2));
|
CPU_Push16(mem_readw(o_stack+i*2));
|
||||||
CPU_Push16(SegValue(cs));
|
CPU_Push16(SegValue(cs));
|
||||||
CPU_Push16(reg_eip);
|
CPU_Push16(oldeip);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cpu.cpl = n_cs_desc.DPL();
|
||||||
/* Switch to new CS:EIP */
|
/* Switch to new CS:EIP */
|
||||||
Segs.phys[cs] = n_cs_desc.GetBase();
|
Segs.phys[cs] = n_cs_desc.GetBase();
|
||||||
Segs.val[cs] = (n_cs_sel & 0xfffc) | cpu.cpl;
|
Segs.val[cs] = (n_cs_sel & 0xfffc) | cpu.cpl;
|
||||||
@ -742,7 +789,7 @@ call_gate_same_privilege:
|
|||||||
if (call.DPL()<cpu.cpl) E_Exit("CALL:TSS:dpl<cpl");
|
if (call.DPL()<cpu.cpl) E_Exit("CALL:TSS:dpl<cpl");
|
||||||
if (call.DPL()<rpl) E_Exit("CALL:TSS:dpl<rpl");
|
if (call.DPL()<rpl) E_Exit("CALL:TSS:dpl<rpl");
|
||||||
LOG(LOG_CPU,LOG_NORMAL)("CALL:TSS to %X",selector);
|
LOG(LOG_CPU,LOG_NORMAL)("CALL:TSS to %X",selector);
|
||||||
CPU_SwitchTask(selector,TSwitch_CALL_INT);
|
CPU_SwitchTask(selector,TSwitch_CALL_INT,oldeip);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
E_Exit("CALL:Descriptor type %x unsupported",call.Type());
|
E_Exit("CALL:Descriptor type %x unsupported",call.Type());
|
||||||
@ -753,7 +800,7 @@ call_gate_same_privilege:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CPU_RET(bool use32,Bitu bytes,Bitu opLen) {
|
void CPU_RET(bool use32,Bitu bytes,Bitu oldeip) {
|
||||||
if (!cpu.pmode || (reg_flags & FLAG_VM)) {
|
if (!cpu.pmode || (reg_flags & FLAG_VM)) {
|
||||||
Bitu new_ip,new_cs;
|
Bitu new_ip,new_cs;
|
||||||
if (!use32) {
|
if (!use32) {
|
||||||
@ -775,11 +822,13 @@ void CPU_RET(bool use32,Bitu bytes,Bitu opLen) {
|
|||||||
|
|
||||||
Descriptor desc;
|
Descriptor desc;
|
||||||
Bitu rpl=selector & 3;
|
Bitu rpl=selector & 3;
|
||||||
if (rpl<cpu.cpl) E_Exit("RET to lower privilege");
|
if (rpl<cpu.cpl) {
|
||||||
|
CPU_Exception(0x0B,selector & 0xfffc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
cpu.gdt.GetDescriptor(selector,desc);
|
cpu.gdt.GetDescriptor(selector,desc);
|
||||||
|
|
||||||
if (!desc.saved.seg.p) {
|
if (!desc.saved.seg.p) {
|
||||||
reg_eip -= opLen;
|
|
||||||
CPU_Exception(0x0B,selector & 0xfffc);
|
CPU_Exception(0x0B,selector & 0xfffc);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
@ -820,7 +869,7 @@ RET_same_level:
|
|||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
/* Return to outer level */
|
/* Return to outer level */
|
||||||
if (bytes) E_Exit("RETF outeer level with immediate value");
|
if (bytes) E_Exit("RETF outer level with immediate value");
|
||||||
Bitu n_esp,n_ss;
|
Bitu n_esp,n_ss;
|
||||||
if (use32) {
|
if (use32) {
|
||||||
n_esp = CPU_Pop32();
|
n_esp = CPU_Pop32();
|
||||||
@ -830,16 +879,19 @@ RET_same_level:
|
|||||||
n_ss = CPU_Pop16();
|
n_ss = CPU_Pop16();
|
||||||
}
|
}
|
||||||
cpu.cpl = rpl;
|
cpu.cpl = rpl;
|
||||||
|
|
||||||
CPU_SetSegGeneral(ss,n_ss);
|
CPU_SetSegGeneral(ss,n_ss);
|
||||||
if (cpu.stack.big) {
|
if (cpu.stack.big) {
|
||||||
reg_esp = n_esp;
|
reg_esp = n_esp;
|
||||||
} else {
|
} else {
|
||||||
reg_sp = n_esp;
|
reg_sp = n_esp;
|
||||||
}
|
}
|
||||||
|
|
||||||
Segs.phys[cs]=desc.GetBase();
|
Segs.phys[cs]=desc.GetBase();
|
||||||
cpu.code.big=desc.Big()>0;
|
cpu.code.big=desc.Big()>0;
|
||||||
Segs.val[cs]=selector;
|
Segs.val[cs]=(selector&0xfffc) | cpu.cpl;
|
||||||
reg_eip=offset;
|
reg_eip=offset;
|
||||||
|
|
||||||
// LOG(LOG_MISC,LOG_ERROR)("RET - Higher level to %X:%X RPL %X DPL %X",selector,offset,rpl,desc.DPL());
|
// LOG(LOG_MISC,LOG_ERROR)("RET - Higher level to %X:%X RPL %X DPL %X",selector,offset,rpl,desc.DPL());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -899,9 +951,8 @@ bool CPU_SET_CRX(Bitu cr,Bitu value) {
|
|||||||
case 0:
|
case 0:
|
||||||
{
|
{
|
||||||
Bitu changed=cpu.cr0 ^ value;
|
Bitu changed=cpu.cr0 ^ value;
|
||||||
if (!changed) return true;
|
if (!changed) return false;
|
||||||
cpu.cr0=value;
|
cpu.cr0=value;
|
||||||
//TODO Maybe always first change to core_full for a change to cr0
|
|
||||||
if (value & CR0_PROTECTION) {
|
if (value & CR0_PROTECTION) {
|
||||||
cpu.pmode=true;
|
cpu.pmode=true;
|
||||||
LOG(LOG_CPU,LOG_NORMAL)("Protected mode");
|
LOG(LOG_CPU,LOG_NORMAL)("Protected mode");
|
||||||
@ -911,7 +962,7 @@ bool CPU_SET_CRX(Bitu cr,Bitu value) {
|
|||||||
PAGING_Enable(false);
|
PAGING_Enable(false);
|
||||||
LOG(LOG_CPU,LOG_NORMAL)("Real mode");
|
LOG(LOG_CPU,LOG_NORMAL)("Real mode");
|
||||||
}
|
}
|
||||||
return false; //Only changes with next CS change
|
break;
|
||||||
}
|
}
|
||||||
case 2:
|
case 2:
|
||||||
paging.cr2=value;
|
paging.cr2=value;
|
||||||
@ -946,11 +997,12 @@ void CPU_SMSW(Bitu & word) {
|
|||||||
word=cpu.cr0;
|
word=cpu.cr0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CPU_LMSW(Bitu word) {
|
Bitu CPU_LMSW(Bitu word) {
|
||||||
word&=0xf;
|
word&=0xf;
|
||||||
if (cpu.cr0 & 1) word|=1;
|
if (cpu.cr0 & 1) word|=1;
|
||||||
word|=(cpu.cr0&0xfffffff0);
|
word|=(cpu.cr0&0xfffffff0);
|
||||||
return CPU_SET_CRX(0,word);
|
CPU_SET_CRX(0,word);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU_ARPL(Bitu & dest_sel,Bitu src_sel) {
|
void CPU_ARPL(Bitu & dest_sel,Bitu src_sel) {
|
||||||
@ -964,8 +1016,11 @@ void CPU_ARPL(Bitu & dest_sel,Bitu src_sel) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CPU_LAR(Bitu selector,Bitu & ar) {
|
void CPU_LAR(Bitu selector,Bitu & ar) {
|
||||||
|
if (selector == 0) {
|
||||||
|
SETFLAGBIT(ZF,false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
Descriptor desc;Bitu rpl=selector & 3;
|
Descriptor desc;Bitu rpl=selector & 3;
|
||||||
ar=0;
|
|
||||||
if (!cpu.gdt.GetDescriptor(selector,desc)){
|
if (!cpu.gdt.GetDescriptor(selector,desc)){
|
||||||
SETFLAGBIT(ZF,false);
|
SETFLAGBIT(ZF,false);
|
||||||
return;
|
return;
|
||||||
@ -975,15 +1030,19 @@ void CPU_LAR(Bitu selector,Bitu & ar) {
|
|||||||
case DESC_CODE_R_C_A: case DESC_CODE_R_C_NA:
|
case DESC_CODE_R_C_A: case DESC_CODE_R_C_NA:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case DESC_286_INT_GATE: case DESC_286_TRAP_GATE: {
|
||||||
|
case DESC_386_INT_GATE: case DESC_386_TRAP_GATE:
|
||||||
|
SETFLAGBIT(ZF,false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
case DESC_LDT:
|
case DESC_LDT:
|
||||||
case DESC_TASK_GATE:
|
case DESC_TASK_GATE:
|
||||||
|
|
||||||
case DESC_286_TSS_A: case DESC_286_TSS_B:
|
case DESC_286_TSS_A: case DESC_286_TSS_B:
|
||||||
case DESC_286_INT_GATE: case DESC_286_TRAP_GATE:
|
|
||||||
case DESC_286_CALL_GATE:
|
case DESC_286_CALL_GATE:
|
||||||
|
|
||||||
case DESC_386_TSS_A: case DESC_386_TSS_B:
|
case DESC_386_TSS_A: case DESC_386_TSS_B:
|
||||||
case DESC_386_INT_GATE: case DESC_386_TRAP_GATE:
|
|
||||||
case DESC_386_CALL_GATE:
|
case DESC_386_CALL_GATE:
|
||||||
|
|
||||||
|
|
||||||
@ -1008,8 +1067,11 @@ void CPU_LAR(Bitu selector,Bitu & ar) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CPU_LSL(Bitu selector,Bitu & limit) {
|
void CPU_LSL(Bitu selector,Bitu & limit) {
|
||||||
|
if (selector == 0) {
|
||||||
|
SETFLAGBIT(ZF,false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
Descriptor desc;Bitu rpl=selector & 3;
|
Descriptor desc;Bitu rpl=selector & 3;
|
||||||
limit=0;
|
|
||||||
if (!cpu.gdt.GetDescriptor(selector,desc)){
|
if (!cpu.gdt.GetDescriptor(selector,desc)){
|
||||||
SETFLAGBIT(ZF,false);
|
SETFLAGBIT(ZF,false);
|
||||||
return;
|
return;
|
||||||
@ -1047,6 +1109,10 @@ void CPU_LSL(Bitu selector,Bitu & limit) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CPU_VERR(Bitu selector) {
|
void CPU_VERR(Bitu selector) {
|
||||||
|
if (selector == 0) {
|
||||||
|
SETFLAGBIT(ZF,false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
Descriptor desc;Bitu rpl=selector & 3;
|
Descriptor desc;Bitu rpl=selector & 3;
|
||||||
if (!cpu.gdt.GetDescriptor(selector,desc)){
|
if (!cpu.gdt.GetDescriptor(selector,desc)){
|
||||||
SETFLAGBIT(ZF,false);
|
SETFLAGBIT(ZF,false);
|
||||||
@ -1075,6 +1141,10 @@ void CPU_VERR(Bitu selector) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void CPU_VERW(Bitu selector) {
|
void CPU_VERW(Bitu selector) {
|
||||||
|
if (selector == 0) {
|
||||||
|
SETFLAGBIT(ZF,false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
Descriptor desc;Bitu rpl=selector & 3;
|
Descriptor desc;Bitu rpl=selector & 3;
|
||||||
if (!cpu.gdt.GetDescriptor(selector,desc)){
|
if (!cpu.gdt.GetDescriptor(selector,desc)){
|
||||||
SETFLAGBIT(ZF,false);
|
SETFLAGBIT(ZF,false);
|
||||||
@ -1113,13 +1183,11 @@ bool CPU_SetSegGeneral(SegNames seg,Bitu value) {
|
|||||||
if (!desc.saved.seg.p) {
|
if (!desc.saved.seg.p) {
|
||||||
if (seg==ss) E_Exit("CPU_SetSegGeneral: Stack segment not present.");
|
if (seg==ss) E_Exit("CPU_SetSegGeneral: Stack segment not present.");
|
||||||
// Throw Exception 0x0B - Segment not present
|
// Throw Exception 0x0B - Segment not present
|
||||||
CPU_SetupException(0x0B,value & 0xfffc);
|
return CPU_PrepareException(0x0B,value & 0xfffc);
|
||||||
return true;
|
|
||||||
} else if (seg==ss) {
|
} else if (seg==ss) {
|
||||||
// Stack segment loaded with illegal segment ?
|
// Stack segment loaded with illegal segment ?
|
||||||
if ((desc.saved.seg.type<DESC_DATA_EU_RO_NA) || (desc.saved.seg.type>DESC_DATA_ED_RW_A)) {
|
if ((desc.saved.seg.type<DESC_DATA_EU_RO_NA) || (desc.saved.seg.type>DESC_DATA_ED_RW_A)) {
|
||||||
CPU_SetupException(0x0D,value & 0xfffc);
|
return CPU_PrepareException(0x0D,value & 0xfffc);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1138,6 +1206,14 @@ bool CPU_SetSegGeneral(SegNames seg,Bitu value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CPU_PopSeg(SegNames seg,bool use32) {
|
||||||
|
Bitu val=mem_readw(SegPhys(ss) + (reg_esp & cpu.stack.mask));
|
||||||
|
if (CPU_SetSegGeneral(seg,val)) return true;
|
||||||
|
Bitu addsp=2 << use32;
|
||||||
|
reg_esp=(reg_esp&~cpu.stack.mask)|((reg_esp+addsp)&cpu.stack.mask);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void CPU_CPUID(void) {
|
void CPU_CPUID(void) {
|
||||||
switch (reg_eax) {
|
switch (reg_eax) {
|
||||||
case 0: /* Vendor ID String and maximum level? */
|
case 0: /* Vendor ID String and maximum level? */
|
||||||
@ -1168,12 +1244,12 @@ static Bits HLT_Decode(void) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU_HLT(Bitu opLen) {
|
void CPU_HLT(Bitu oldeip) {
|
||||||
if (cpu.cpl) {
|
if (cpu.cpl) {
|
||||||
reg_eip-=opLen;
|
|
||||||
CPU_Exception(13,0);
|
CPU_Exception(13,0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
reg_eip=oldeip;
|
||||||
CPU_Cycles=0;
|
CPU_Cycles=0;
|
||||||
cpu.hlt.cs=SegValue(cs);
|
cpu.hlt.cs=SegValue(cs);
|
||||||
cpu.hlt.eip=reg_eip;
|
cpu.hlt.eip=reg_eip;
|
||||||
@ -1182,8 +1258,40 @@ void CPU_HLT(Bitu opLen) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CPU_ENTER(bool use32,Bitu bytes,Bitu level) {
|
||||||
|
level&=0x1f;
|
||||||
|
Bitu sp_index=reg_esp&cpu.stack.mask;
|
||||||
|
Bitu bp_index=reg_ebp&cpu.stack.mask;
|
||||||
|
if (!use32) {
|
||||||
|
sp_index-=2;
|
||||||
|
mem_writew(SegPhys(ss)+sp_index,reg_bp);
|
||||||
|
reg_bp=(Bit16u)(reg_esp-2);
|
||||||
|
if (level) {
|
||||||
|
for (Bitu i=1;i<level;i++) {
|
||||||
|
sp_index-=2;bp_index-=2;
|
||||||
|
mem_writew(SegPhys(ss)+sp_index,mem_readw(SegPhys(ss)+bp_index));
|
||||||
|
}
|
||||||
|
sp_index-=2;
|
||||||
|
mem_writew(SegPhys(ss)+sp_index,reg_bp);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sp_index-=4;
|
||||||
|
mem_writed(SegPhys(ss)+sp_index,reg_ebp);
|
||||||
|
reg_ebp=(reg_esp-4);
|
||||||
|
if (level) {
|
||||||
|
for (Bitu i=1;i<level;i++) {
|
||||||
|
sp_index-=4;bp_index-=4;
|
||||||
|
mem_writed(SegPhys(ss)+sp_index,mem_readd(SegPhys(ss)+bp_index));
|
||||||
|
}
|
||||||
|
sp_index-=4;
|
||||||
|
mem_writed(SegPhys(ss)+sp_index,reg_ebp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sp_index-=bytes;
|
||||||
|
reg_esp=(reg_esp&~cpu.stack.mask)|((sp_index)&cpu.stack.mask);
|
||||||
|
}
|
||||||
|
|
||||||
extern void GFX_SetTitle(Bits cycles ,Bits frameskip);
|
extern void GFX_SetTitle(Bits cycles ,Bits frameskip,bool paused);
|
||||||
static void CPU_CycleIncrease(void) {
|
static void CPU_CycleIncrease(void) {
|
||||||
Bits old_cycles=CPU_CycleMax;
|
Bits old_cycles=CPU_CycleMax;
|
||||||
if(CPU_CycleUp < 100){
|
if(CPU_CycleUp < 100){
|
||||||
@ -1195,7 +1303,7 @@ static void CPU_CycleIncrease(void) {
|
|||||||
CPU_CycleLeft=0;CPU_Cycles=0;
|
CPU_CycleLeft=0;CPU_Cycles=0;
|
||||||
if (CPU_CycleMax==old_cycles) CPU_CycleMax++;
|
if (CPU_CycleMax==old_cycles) CPU_CycleMax++;
|
||||||
LOG_MSG("CPU:%d cycles",CPU_CycleMax);
|
LOG_MSG("CPU:%d cycles",CPU_CycleMax);
|
||||||
GFX_SetTitle(CPU_CycleMax,-1);
|
GFX_SetTitle(CPU_CycleMax,-1,false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void CPU_CycleDecrease(void) {
|
static void CPU_CycleDecrease(void) {
|
||||||
@ -1207,10 +1315,9 @@ static void CPU_CycleDecrease(void) {
|
|||||||
CPU_CycleLeft=0;CPU_Cycles=0;
|
CPU_CycleLeft=0;CPU_Cycles=0;
|
||||||
if (CPU_CycleMax <= 0) CPU_CycleMax=1;
|
if (CPU_CycleMax <= 0) CPU_CycleMax=1;
|
||||||
LOG_MSG("CPU:%d cycles",CPU_CycleMax);
|
LOG_MSG("CPU:%d cycles",CPU_CycleMax);
|
||||||
GFX_SetTitle(CPU_CycleMax,-1);
|
GFX_SetTitle(CPU_CycleMax,-1,false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void CPU_Init(Section* sec) {
|
void CPU_Init(Section* sec) {
|
||||||
Section_prop * section=static_cast<Section_prop *>(sec);
|
Section_prop * section=static_cast<Section_prop *>(sec);
|
||||||
reg_eax=0;
|
reg_eax=0;
|
||||||
@ -1240,14 +1347,13 @@ void CPU_Init(Section* sec) {
|
|||||||
|
|
||||||
/* Init the cpu cores */
|
/* Init the cpu cores */
|
||||||
CPU_Core_Normal_Init();
|
CPU_Core_Normal_Init();
|
||||||
|
CPU_Core_Simple_Init();
|
||||||
CPU_Core_Full_Init();
|
CPU_Core_Full_Init();
|
||||||
#if (C_DYNAMIC_X86)
|
#if (C_DYNAMIC_X86)
|
||||||
CPU_Core_Dyn_X86_Init();
|
CPU_Core_Dyn_X86_Init();
|
||||||
#endif
|
#endif
|
||||||
|
MAPPER_AddHandler(CPU_CycleDecrease,MK_f11,MMOD1,"cycledown","Dec Cycles");
|
||||||
KEYBOARD_AddEvent(KBD_f11,KBD_MOD_CTRL,CPU_CycleDecrease);
|
MAPPER_AddHandler(CPU_CycleIncrease,MK_f12,MMOD1,"cycleup" ,"Inc Cycles");
|
||||||
KEYBOARD_AddEvent(KBD_f12,KBD_MOD_CTRL,CPU_CycleIncrease);
|
|
||||||
|
|
||||||
CPU_Cycles=0;
|
CPU_Cycles=0;
|
||||||
CPU_CycleMax=section->Get_int("cycles");;
|
CPU_CycleMax=section->Get_int("cycles");;
|
||||||
CPU_CycleUp=section->Get_int("cycleup");
|
CPU_CycleUp=section->Get_int("cycleup");
|
||||||
@ -1256,6 +1362,8 @@ void CPU_Init(Section* sec) {
|
|||||||
cpudecoder=&CPU_Core_Normal_Run;
|
cpudecoder=&CPU_Core_Normal_Run;
|
||||||
if (!strcasecmp(core,"normal")) {
|
if (!strcasecmp(core,"normal")) {
|
||||||
cpudecoder=&CPU_Core_Normal_Run;
|
cpudecoder=&CPU_Core_Normal_Run;
|
||||||
|
} else if (!strcasecmp(core,"simple")) {
|
||||||
|
cpudecoder=&CPU_Core_Simple_Run;
|
||||||
} else if (!strcasecmp(core,"full")) {
|
} else if (!strcasecmp(core,"full")) {
|
||||||
cpudecoder=&CPU_Core_Full_Run;
|
cpudecoder=&CPU_Core_Full_Run;
|
||||||
}
|
}
|
||||||
@ -1267,12 +1375,12 @@ void CPU_Init(Section* sec) {
|
|||||||
else {
|
else {
|
||||||
LOG_MSG("CPU:Unknown core type %s, switcing back to normal.",core);
|
LOG_MSG("CPU:Unknown core type %s, switcing back to normal.",core);
|
||||||
}
|
}
|
||||||
CPU_JMP(false,0,0); //Setup the first cpu core
|
CPU_JMP(false,0,0,0); //Setup the first cpu core
|
||||||
|
|
||||||
if (!CPU_CycleMax) CPU_CycleMax = 2500;
|
if (!CPU_CycleMax) CPU_CycleMax = 2500;
|
||||||
if(!CPU_CycleUp) CPU_CycleUp = 500;
|
if(!CPU_CycleUp) CPU_CycleUp = 500;
|
||||||
if(!CPU_CycleDown) CPU_CycleDown = 20;
|
if(!CPU_CycleDown) CPU_CycleDown = 20;
|
||||||
CPU_CycleLeft=0;
|
CPU_CycleLeft=0;
|
||||||
GFX_SetTitle(CPU_CycleMax,-1);
|
GFX_SetTitle(CPU_CycleMax,-1,false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
@ -548,7 +548,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define MULB(op1,load,save) \
|
#define MULB(op1,load,save) \
|
||||||
lflags.type=t_MUL; \
|
FillFlags(); \
|
||||||
reg_ax=reg_al*load(op1); \
|
reg_ax=reg_al*load(op1); \
|
||||||
if (reg_ax & 0xff00) { \
|
if (reg_ax & 0xff00) { \
|
||||||
SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \
|
SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \
|
||||||
@ -558,10 +558,10 @@
|
|||||||
|
|
||||||
#define MULW(op1,load,save) \
|
#define MULW(op1,load,save) \
|
||||||
{ \
|
{ \
|
||||||
|
FillFlags(); \
|
||||||
Bitu tempu=(Bitu)reg_ax*(Bitu)(load(op1)); \
|
Bitu tempu=(Bitu)reg_ax*(Bitu)(load(op1)); \
|
||||||
reg_ax=(Bit16u)(tempu); \
|
reg_ax=(Bit16u)(tempu); \
|
||||||
reg_dx=(Bit16u)(tempu >> 16); \
|
reg_dx=(Bit16u)(tempu >> 16); \
|
||||||
lflags.type=t_MUL; \
|
|
||||||
if (reg_dx) { \
|
if (reg_dx) { \
|
||||||
SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \
|
SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \
|
||||||
} else { \
|
} else { \
|
||||||
@ -571,10 +571,10 @@
|
|||||||
|
|
||||||
#define MULD(op1,load,save) \
|
#define MULD(op1,load,save) \
|
||||||
{ \
|
{ \
|
||||||
|
FillFlags(); \
|
||||||
Bit64u tempu=(Bit64u)reg_eax*(Bit64u)(load(op1)); \
|
Bit64u tempu=(Bit64u)reg_eax*(Bit64u)(load(op1)); \
|
||||||
reg_eax=(Bit32u)(tempu); \
|
reg_eax=(Bit32u)(tempu); \
|
||||||
reg_edx=(Bit32u)(tempu >> 32); \
|
reg_edx=(Bit32u)(tempu >> 32); \
|
||||||
lflags.type=t_MUL; \
|
|
||||||
if (reg_edx) { \
|
if (reg_edx) { \
|
||||||
SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \
|
SETFLAGBIT(CF,true);SETFLAGBIT(OF,true); \
|
||||||
} else { \
|
} else { \
|
||||||
@ -651,7 +651,7 @@
|
|||||||
|
|
||||||
#define IMULB(op1,load,save) \
|
#define IMULB(op1,load,save) \
|
||||||
{ \
|
{ \
|
||||||
lflags.type=t_MUL; \
|
FillFlags(); \
|
||||||
reg_ax=((Bit8s)reg_al) * ((Bit8s)(load(op1))); \
|
reg_ax=((Bit8s)reg_al) * ((Bit8s)(load(op1))); \
|
||||||
if ((reg_ax & 0xff80)==0xff80 || \
|
if ((reg_ax & 0xff80)==0xff80 || \
|
||||||
(reg_ax & 0xff80)==0x0000) { \
|
(reg_ax & 0xff80)==0x0000) { \
|
||||||
@ -664,10 +664,10 @@
|
|||||||
|
|
||||||
#define IMULW(op1,load,save) \
|
#define IMULW(op1,load,save) \
|
||||||
{ \
|
{ \
|
||||||
|
FillFlags(); \
|
||||||
Bits temps=((Bit16s)reg_ax)*((Bit16s)(load(op1))); \
|
Bits temps=((Bit16s)reg_ax)*((Bit16s)(load(op1))); \
|
||||||
reg_ax=(Bit16s)(temps); \
|
reg_ax=(Bit16s)(temps); \
|
||||||
reg_dx=(Bit16s)(temps >> 16); \
|
reg_dx=(Bit16s)(temps >> 16); \
|
||||||
lflags.type=t_MUL; \
|
|
||||||
if (((temps & 0xffff8000)==0xffff8000 || \
|
if (((temps & 0xffff8000)==0xffff8000 || \
|
||||||
(temps & 0xffff8000)==0x0000)) { \
|
(temps & 0xffff8000)==0x0000)) { \
|
||||||
SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \
|
SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \
|
||||||
@ -678,11 +678,11 @@
|
|||||||
|
|
||||||
#define IMULD(op1,load,save) \
|
#define IMULD(op1,load,save) \
|
||||||
{ \
|
{ \
|
||||||
|
FillFlags(); \
|
||||||
Bit64s temps=((Bit64s)((Bit32s)reg_eax))* \
|
Bit64s temps=((Bit64s)((Bit32s)reg_eax))* \
|
||||||
((Bit64s)((Bit32s)(load(op1)))); \
|
((Bit64s)((Bit32s)(load(op1)))); \
|
||||||
reg_eax=(Bit32u)(temps); \
|
reg_eax=(Bit32u)(temps); \
|
||||||
reg_edx=(Bit32u)(temps >> 32); \
|
reg_edx=(Bit32u)(temps >> 32); \
|
||||||
lflags.type=t_MUL; \
|
|
||||||
if ((reg_edx==0xffffffff) && \
|
if ((reg_edx==0xffffffff) && \
|
||||||
(reg_eax & 0x80000000) ) { \
|
(reg_eax & 0x80000000) ) { \
|
||||||
SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \
|
SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \
|
||||||
@ -696,10 +696,10 @@
|
|||||||
|
|
||||||
#define DIMULW(op1,op2,op3,load,save) \
|
#define DIMULW(op1,op2,op3,load,save) \
|
||||||
{ \
|
{ \
|
||||||
|
FillFlags(); \
|
||||||
Bits res; \
|
Bits res; \
|
||||||
res=((Bit16s)op2) * ((Bit16s)op3); \
|
res=((Bit16s)op2) * ((Bit16s)op3); \
|
||||||
save(op1,res & 0xffff); \
|
save(op1,res & 0xffff); \
|
||||||
lflags.type=t_MUL; \
|
|
||||||
if ((res> -32768) && (res<32767)) { \
|
if ((res> -32768) && (res<32767)) { \
|
||||||
SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \
|
SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \
|
||||||
} else { \
|
} else { \
|
||||||
@ -709,9 +709,9 @@
|
|||||||
|
|
||||||
#define DIMULD(op1,op2,op3,load,save) \
|
#define DIMULD(op1,op2,op3,load,save) \
|
||||||
{ \
|
{ \
|
||||||
|
FillFlags(); \
|
||||||
Bit64s res=((Bit64s)((Bit32s)op2))*((Bit64s)((Bit32s)op3)); \
|
Bit64s res=((Bit64s)((Bit32s)op2))*((Bit64s)((Bit32s)op3)); \
|
||||||
save(op1,(Bit32s)res); \
|
save(op1,(Bit32s)res); \
|
||||||
lflags.type=t_MUL; \
|
|
||||||
if ((res>-((Bit64s)(2147483647)+1)) && \
|
if ((res>-((Bit64s)(2147483647)+1)) && \
|
||||||
(res<(Bit64s)2147483647)) { \
|
(res<(Bit64s)2147483647)) { \
|
||||||
SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \
|
SETFLAGBIT(CF,false);SETFLAGBIT(OF,false); \
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
@ -93,7 +93,7 @@ static Bits PageFaultCore(void) {
|
|||||||
if (!pf_queue.used) E_Exit("PF Core without PF");
|
if (!pf_queue.used) E_Exit("PF Core without PF");
|
||||||
PF_Entry * entry=&pf_queue.entries[pf_queue.used-1];
|
PF_Entry * entry=&pf_queue.entries[pf_queue.used-1];
|
||||||
X86PageEntry pentry;
|
X86PageEntry pentry;
|
||||||
pentry.load=MEM_PhysReadD(entry->page_addr);
|
pentry.load=phys_readd(entry->page_addr);
|
||||||
if (pentry.block.p && entry->cs == SegValue(cs) && entry->eip==reg_eip)
|
if (pentry.block.p && entry->cs == SegValue(cs) && entry->eip==reg_eip)
|
||||||
return -1;
|
return -1;
|
||||||
return 0;
|
return 0;
|
||||||
@ -102,6 +102,8 @@ static Bits PageFaultCore(void) {
|
|||||||
Bitu DEBUG_EnableDebugger(void);
|
Bitu DEBUG_EnableDebugger(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bool first=false;
|
||||||
|
|
||||||
void PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,Bitu type) {
|
void PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,Bitu type) {
|
||||||
/* Save the state of the cpu cores */
|
/* Save the state of the cpu cores */
|
||||||
LazyFlags old_lflags;
|
LazyFlags old_lflags;
|
||||||
@ -112,6 +114,8 @@ void PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,Bitu type) {
|
|||||||
paging.cr2=lin_addr;
|
paging.cr2=lin_addr;
|
||||||
PF_Entry * entry=&pf_queue.entries[pf_queue.used++];
|
PF_Entry * entry=&pf_queue.entries[pf_queue.used++];
|
||||||
LOG(LOG_PAGING,LOG_NORMAL)("PageFault at %X type %d queue %d",lin_addr,type,pf_queue.used);
|
LOG(LOG_PAGING,LOG_NORMAL)("PageFault at %X type %d queue %d",lin_addr,type,pf_queue.used);
|
||||||
|
// LOG_MSG("EAX:%04X ECX:%04X EDX:%04X EBX:%04X",reg_eax,reg_ecx,reg_edx,reg_ebx);
|
||||||
|
// LOG_MSG("CS:%04X EIP:%08X SS:%04x SP:%08X",SegValue(cs),reg_eip,SegValue(ss),reg_esp);
|
||||||
entry->cs=SegValue(cs);
|
entry->cs=SegValue(cs);
|
||||||
entry->eip=reg_eip;
|
entry->eip=reg_eip;
|
||||||
entry->page_addr=page_addr;
|
entry->page_addr=page_addr;
|
||||||
@ -125,10 +129,9 @@ void PAGING_PageFault(PhysPt lin_addr,Bitu page_addr,Bitu type) {
|
|||||||
LOG(LOG_PAGING,LOG_NORMAL)("Left PageFault for %x queue %d",lin_addr,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));
|
memcpy(&lflags,&old_lflags,sizeof(LazyFlags));
|
||||||
cpudecoder=old_cpudecoder;
|
cpudecoder=old_cpudecoder;
|
||||||
|
// LOG_MSG("SS:%04x SP:%08X",SegValue(ss),reg_esp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void MEM_PhysWriteD(Bitu addr,Bit32u val);
|
|
||||||
class InitPageHandler : public PageHandler {
|
class InitPageHandler : public PageHandler {
|
||||||
public:
|
public:
|
||||||
InitPageHandler() {flags=PFLAG_INIT|PFLAG_NOCODE;}
|
InitPageHandler() {flags=PFLAG_INIT|PFLAG_NOCODE;}
|
||||||
@ -164,28 +167,28 @@ public:
|
|||||||
Bitu t_index=lin_page & 0x3ff;
|
Bitu t_index=lin_page & 0x3ff;
|
||||||
Bitu table_addr=(paging.base.page<<12)+d_index*4;
|
Bitu table_addr=(paging.base.page<<12)+d_index*4;
|
||||||
X86PageEntry table;
|
X86PageEntry table;
|
||||||
table.load=MEM_PhysReadD(table_addr);
|
table.load=phys_readd(table_addr);
|
||||||
if (!table.block.p) {
|
if (!table.block.p) {
|
||||||
LOG(LOG_PAGING,LOG_ERROR)("NP Table");
|
LOG(LOG_PAGING,LOG_ERROR)("NP Table");
|
||||||
PAGING_PageFault(lin_addr,table_addr,0);
|
PAGING_PageFault(lin_addr,table_addr,0);
|
||||||
table.load=MEM_PhysReadD(table_addr);
|
table.load=phys_readd(table_addr);
|
||||||
if (!table.block.p)
|
if (!table.block.p)
|
||||||
E_Exit("Pagefault didn't correct table");
|
E_Exit("Pagefault didn't correct table");
|
||||||
}
|
}
|
||||||
table.block.a=table.block.d=1; //Set access/Dirty
|
table.block.a=table.block.d=1; //Set access/Dirty
|
||||||
MEM_PhysWriteD(table_addr,table.load);
|
phys_writed(table_addr,table.load);
|
||||||
X86PageEntry entry;
|
X86PageEntry entry;
|
||||||
Bitu entry_addr=(table.block.base<<12)+t_index*4;
|
Bitu entry_addr=(table.block.base<<12)+t_index*4;
|
||||||
entry.load=MEM_PhysReadD(entry_addr);
|
entry.load=phys_readd(entry_addr);
|
||||||
if (!entry.block.p) {
|
if (!entry.block.p) {
|
||||||
LOG(LOG_PAGING,LOG_ERROR)("NP Page");
|
LOG(LOG_PAGING,LOG_ERROR)("NP Page");
|
||||||
PAGING_PageFault(lin_addr,entry_addr,0);
|
PAGING_PageFault(lin_addr,entry_addr,0);
|
||||||
entry.load=MEM_PhysReadD(entry_addr);
|
entry.load=phys_readd(entry_addr);
|
||||||
if (!entry.block.p)
|
if (!entry.block.p)
|
||||||
E_Exit("Pagefault didn't correct page");
|
E_Exit("Pagefault didn't correct page");
|
||||||
}
|
}
|
||||||
entry.block.a=entry.block.d=1; //Set access/Dirty
|
entry.block.a=entry.block.d=1; //Set access/Dirty
|
||||||
MEM_PhysWriteD(entry_addr,entry.load);
|
phys_writed(entry_addr,entry.load);
|
||||||
phys_page=entry.block.base;
|
phys_page=entry.block.base;
|
||||||
} else {
|
} else {
|
||||||
if (lin_page<LINK_START) phys_page=mapfirstmb[lin_page];
|
if (lin_page<LINK_START) phys_page=mapfirstmb[lin_page];
|
||||||
@ -200,10 +203,10 @@ bool PAGING_MakePhysPage(Bitu & page) {
|
|||||||
Bitu d_index=page >> 10;
|
Bitu d_index=page >> 10;
|
||||||
Bitu t_index=page & 0x3ff;
|
Bitu t_index=page & 0x3ff;
|
||||||
X86PageEntry table;
|
X86PageEntry table;
|
||||||
table.load=MEM_PhysReadD((paging.base.page<<12)+d_index*4);
|
table.load=phys_readd((paging.base.page<<12)+d_index*4);
|
||||||
if (!table.block.p) return false;
|
if (!table.block.p) return false;
|
||||||
X86PageEntry entry;
|
X86PageEntry entry;
|
||||||
entry.load=MEM_PhysReadD((table.block.base<<12)+t_index*4);
|
entry.load=phys_readd((table.block.base<<12)+t_index*4);
|
||||||
if (!entry.block.p) return false;
|
if (!entry.block.p) return false;
|
||||||
page=entry.block.base;
|
page=entry.block.base;
|
||||||
} else {
|
} else {
|
||||||
@ -251,16 +254,21 @@ void PAGING_UnlinkPages(Bitu lin_page,Bitu pages) {
|
|||||||
void PAGING_LinkPage(Bitu lin_page,Bitu phys_page) {
|
void PAGING_LinkPage(Bitu lin_page,Bitu phys_page) {
|
||||||
PageHandler * handler=MEM_GetPageHandler(phys_page);
|
PageHandler * handler=MEM_GetPageHandler(phys_page);
|
||||||
Bitu lin_base=lin_page << 12;
|
Bitu lin_base=lin_page << 12;
|
||||||
|
|
||||||
if (lin_page>=TLB_SIZE || phys_page>=TLB_SIZE)
|
if (lin_page>=TLB_SIZE || phys_page>=TLB_SIZE)
|
||||||
E_Exit("Illegal page");
|
E_Exit("Illegal page");
|
||||||
|
|
||||||
|
if (paging.links.used>=PAGING_LINKS) {
|
||||||
|
LOG(LOG_PAGING,LOG_NORMAL)("Not enough paging links, resetting cache");
|
||||||
|
PAGING_ClearTLB();
|
||||||
|
}
|
||||||
|
|
||||||
HostPt host_mem=handler->GetHostPt(phys_page);
|
HostPt host_mem=handler->GetHostPt(phys_page);
|
||||||
paging.tlb.phys_page[lin_page]=phys_page;
|
paging.tlb.phys_page[lin_page]=phys_page;
|
||||||
if (handler->flags & PFLAG_READABLE) paging.tlb.read[lin_page]=host_mem-lin_base;
|
if (handler->flags & PFLAG_READABLE) paging.tlb.read[lin_page]=host_mem-lin_base;
|
||||||
else paging.tlb.read[lin_page]=0;
|
else paging.tlb.read[lin_page]=0;
|
||||||
if (handler->flags & PFLAG_WRITEABLE) paging.tlb.write[lin_page]=host_mem-lin_base;
|
if (handler->flags & PFLAG_WRITEABLE) paging.tlb.write[lin_page]=host_mem-lin_base;
|
||||||
else paging.tlb.write[lin_page]=0;
|
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.links.entries[paging.links.used++]=lin_page;
|
||||||
paging.tlb.handler[lin_page]=handler;
|
paging.tlb.handler[lin_page]=handler;
|
||||||
}
|
}
|
||||||
@ -281,7 +289,7 @@ void PAGING_SetDirBase(Bitu cr3) {
|
|||||||
|
|
||||||
paging.base.page=cr3 >> 12;
|
paging.base.page=cr3 >> 12;
|
||||||
paging.base.addr=cr3 & ~4095;
|
paging.base.addr=cr3 & ~4095;
|
||||||
LOG(LOG_PAGING,LOG_NORMAL)("CR3:%X Base %X",cr3,paging.base.page);
|
// LOG(LOG_PAGING,LOG_NORMAL)("CR3:%X Base %X",cr3,paging.base.page);
|
||||||
if (paging.enabled) {
|
if (paging.enabled) {
|
||||||
PAGING_ClearTLB();
|
PAGING_ClearTLB();
|
||||||
}
|
}
|
||||||
@ -292,9 +300,15 @@ void PAGING_Enable(bool enabled) {
|
|||||||
if (paging.enabled==enabled) return;
|
if (paging.enabled==enabled) return;
|
||||||
paging.enabled=enabled;
|
paging.enabled=enabled;
|
||||||
if (!enabled) {
|
if (!enabled) {
|
||||||
LOG(LOG_PAGING,LOG_NORMAL)("Disabled");
|
// LOG(LOG_PAGING,LOG_NORMAL)("Disabled");
|
||||||
} else {
|
} else {
|
||||||
LOG(LOG_PAGING,LOG_NORMAL)("Enabled");
|
if (cpudecoder==CPU_Core_Simple_Run) {
|
||||||
|
LOG_MSG("CPU core simple won't run this game,switching to normal");
|
||||||
|
cpudecoder=CPU_Core_Normal_Run;
|
||||||
|
CPU_CycleLeft+=CPU_Cycles;
|
||||||
|
CPU_Cycles=0;
|
||||||
|
}
|
||||||
|
// LOG(LOG_PAGING,LOG_NORMAL)("Enabled");
|
||||||
PAGING_SetDirBase(paging.cr3);
|
PAGING_SetDirBase(paging.cr3);
|
||||||
}
|
}
|
||||||
PAGING_ClearTLB();
|
PAGING_ClearTLB();
|
||||||
|
@ -9,16 +9,14 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: debug.cpp,v 1.52 2004/01/27 14:52:28 qbix79 Exp $ */
|
/* $Id: debug.cpp,v 1.59 2004/08/31 23:11:35 harekiet Exp $ */
|
||||||
|
|
||||||
#include "programs.h"
|
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <list>
|
#include <list>
|
||||||
@ -26,19 +24,21 @@
|
|||||||
#include "dosbox.h"
|
#include "dosbox.h"
|
||||||
#if C_DEBUG
|
#if C_DEBUG
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
#include "cross.h" //snprintf
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
#include "pic.h"
|
#include "pic.h"
|
||||||
#include "keyboard.h"
|
#include "mapper.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "callback.h"
|
#include "callback.h"
|
||||||
#include "inout.h"
|
#include "inout.h"
|
||||||
#include "mixer.h"
|
#include "mixer.h"
|
||||||
#include "debug_inc.h"
|
|
||||||
#include "timer.h"
|
#include "timer.h"
|
||||||
#include "paging.h"
|
#include "paging.h"
|
||||||
#include "../ints/xms.h"
|
#include "support.h"
|
||||||
#include "shell.h"
|
#include "shell.h"
|
||||||
|
#include "programs.h"
|
||||||
|
#include "debug_inc.h"
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
void WIN32_Console();
|
void WIN32_Console();
|
||||||
@ -53,13 +53,17 @@ int old_cursor_state;
|
|||||||
static void DrawCode(void);
|
static void DrawCode(void);
|
||||||
static bool DEBUG_Log_Loop(int count);
|
static bool DEBUG_Log_Loop(int count);
|
||||||
static void DEBUG_RaiseTimerIrq(void);
|
static void DEBUG_RaiseTimerIrq(void);
|
||||||
|
static void SaveMemory(Bitu seg, Bitu ofs1, Bit32s num);
|
||||||
|
static void LogGDT(void);
|
||||||
|
static void LogLDT(void);
|
||||||
|
static void LogIDT(void);
|
||||||
|
static void OutputVecTable(char* filename);
|
||||||
|
static void DrawVariables(void);
|
||||||
|
|
||||||
char* AnalyzeInstruction(char* inst, bool saveSelector);
|
char* AnalyzeInstruction(char* inst, bool saveSelector);
|
||||||
void SaveMemory(Bitu seg, Bitu ofs1, Bit32s num);
|
|
||||||
Bit32u GetHexValue(char* str, char*& hex);
|
Bit32u GetHexValue(char* str, char*& hex);
|
||||||
void LogGDT(void);
|
|
||||||
void LogLDT(void);
|
|
||||||
void LogIDT(void);
|
|
||||||
void OutputVecTable(char* filename);
|
|
||||||
|
|
||||||
class DEBUG;
|
class DEBUG;
|
||||||
|
|
||||||
@ -67,6 +71,7 @@ DEBUG* pDebugcom = 0;
|
|||||||
bool exitLoop = false;
|
bool exitLoop = false;
|
||||||
bool logHeavy = false;
|
bool logHeavy = false;
|
||||||
|
|
||||||
|
|
||||||
// Heavy Debugging Vars for logging
|
// Heavy Debugging Vars for logging
|
||||||
#if C_HEAVY_DEBUG
|
#if C_HEAVY_DEBUG
|
||||||
static FILE* cpuLogFile = 0;
|
static FILE* cpuLogFile = 0;
|
||||||
@ -74,6 +79,8 @@ static bool cpuLog = false;
|
|||||||
static int cpuLogCounter = 0;
|
static int cpuLogCounter = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
Bit32u eax,ebx,ecx,edx,esi,edi,ebp,esp,eip;
|
Bit32u eax,ebx,ecx,edx,esi,edi,ebp,esp,eip;
|
||||||
} oldregs;
|
} oldregs;
|
||||||
@ -86,6 +93,8 @@ DBGBlock dbg;
|
|||||||
static Bitu input_count;
|
static Bitu input_count;
|
||||||
Bitu cycle_count;
|
Bitu cycle_count;
|
||||||
static bool debugging;
|
static bool debugging;
|
||||||
|
|
||||||
|
|
||||||
static void SetColor(Bitu test) {
|
static void SetColor(Bitu test) {
|
||||||
if (test) {
|
if (test) {
|
||||||
if (has_colors()) { wattrset(dbg.win_reg,COLOR_PAIR(PAIR_BYELLOW_BLACK));}
|
if (has_colors()) { wattrset(dbg.win_reg,COLOR_PAIR(PAIR_BYELLOW_BLACK));}
|
||||||
@ -535,35 +544,26 @@ void CBreakpoint::ShowList(void)
|
|||||||
bool DEBUG_Breakpoint(void)
|
bool DEBUG_Breakpoint(void)
|
||||||
{
|
{
|
||||||
/* First get the phyiscal address and check for a set Breakpoint */
|
/* First get the phyiscal address and check for a set Breakpoint */
|
||||||
// PhysPt where=SegPhys(cs)+reg_eip-1;
|
PhysPt where=GetAddress(SegValue(cs),reg_eip);
|
||||||
PhysPt where=GetAddress(SegValue(cs),reg_eip-1);
|
if (!CBreakpoint::CheckBreakpoint(SegValue(cs),reg_eip)) return false;
|
||||||
if (!CBreakpoint::CheckBreakpoint(SegValue(cs),reg_eip-1)) return false;
|
|
||||||
// Found. Breakpoint is valid
|
// Found. Breakpoint is valid
|
||||||
reg_eip -= 1;
|
|
||||||
CBreakpoint::ActivateBreakpoints(where,false); // Deactivate all breakpoints
|
CBreakpoint::ActivateBreakpoints(where,false); // Deactivate all breakpoints
|
||||||
// exitLoop = true;
|
|
||||||
// DEBUG_Enable();
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool DEBUG_IntBreakpoint(Bit8u intNum)
|
bool DEBUG_IntBreakpoint(Bit8u intNum)
|
||||||
{
|
{
|
||||||
/* First get the phyiscal address and check for a set Breakpoint */
|
/* First get the phyiscal address and check for a set Breakpoint */
|
||||||
// PhysPt where=SegPhys(cs)+reg_eip-2;
|
PhysPt where=GetAddress(SegValue(cs),reg_eip);
|
||||||
PhysPt where=GetAddress(SegValue(cs),reg_eip-2);
|
|
||||||
if (!CBreakpoint::CheckIntBreakpoint(where,intNum,reg_ah)) return false;
|
if (!CBreakpoint::CheckIntBreakpoint(where,intNum,reg_ah)) return false;
|
||||||
// Found. Breakpoint is valid
|
// Found. Breakpoint is valid
|
||||||
reg_eip -= 2;
|
|
||||||
CBreakpoint::ActivateBreakpoints(where,false); // Deactivate all breakpoints
|
CBreakpoint::ActivateBreakpoints(where,false); // Deactivate all breakpoints
|
||||||
// exitLoop = true;
|
|
||||||
// DEBUG_Enable();
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool StepOver()
|
static bool StepOver()
|
||||||
{
|
{
|
||||||
exitLoop = false;
|
exitLoop = false;
|
||||||
// PhysPt start=SegPhys(cs)+reg_eip;
|
|
||||||
PhysPt start=GetAddress(SegValue(cs),reg_eip);
|
PhysPt start=GetAddress(SegValue(cs),reg_eip);
|
||||||
char dline[200];Bitu size;
|
char dline[200];Bitu size;
|
||||||
size=DasmI386(dline, start, reg_eip, cpu.code.big);
|
size=DasmI386(dline, start, reg_eip, cpu.code.big);
|
||||||
@ -581,6 +581,10 @@ static bool StepOver()
|
|||||||
|
|
||||||
bool DEBUG_ExitLoop(void)
|
bool DEBUG_ExitLoop(void)
|
||||||
{
|
{
|
||||||
|
#if C_HEAVY_DEBUG
|
||||||
|
DrawVariables();
|
||||||
|
#endif
|
||||||
|
|
||||||
if (exitLoop) {
|
if (exitLoop) {
|
||||||
exitLoop = false;
|
exitLoop = false;
|
||||||
return true;
|
return true;
|
||||||
@ -911,6 +915,30 @@ bool ParseCommand(char* str)
|
|||||||
else DEBUG_ShowMsg("DEBUG: Variable list load (%s) : failure",name);
|
else DEBUG_ShowMsg("DEBUG: Variable list load (%s) : failure",name);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
found = strstr(str,"SR ");
|
||||||
|
if (found) { // Set register value
|
||||||
|
found+=2;
|
||||||
|
if (ChangeRegister(found)) DEBUG_ShowMsg("DEBUG: Set Register success.");
|
||||||
|
else DEBUG_ShowMsg("DEBUG: Set Register failure.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
found = strstr(str,"SM ");
|
||||||
|
if (found) { // Set memory with following values
|
||||||
|
found+=3;
|
||||||
|
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 = (Bit8u)GetHexValue(found,found); found++;
|
||||||
|
mem_writeb(GetAddress(seg,ofs+count),value);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
DEBUG_ShowMsg("DEBUG: Memory changed.");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
found = strstr(str,"BP ");
|
found = strstr(str,"BP ");
|
||||||
if (found) { // Add new breakpoint
|
if (found) { // Add new breakpoint
|
||||||
@ -1025,30 +1053,6 @@ bool ParseCommand(char* str)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
found = strstr(str,"SR ");
|
|
||||||
if (found) { // Set register value
|
|
||||||
found+=2;
|
|
||||||
if (ChangeRegister(found)) DEBUG_ShowMsg("DEBUG: Set Register success.");
|
|
||||||
else DEBUG_ShowMsg("DEBUG: Set Register failure.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
found = strstr(str,"SM ");
|
|
||||||
if (found) { // Set memory with following values
|
|
||||||
found+=3;
|
|
||||||
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 = (Bit8u)GetHexValue(found,found); found++;
|
|
||||||
mem_writeb(GetAddress(seg,ofs+count),value);
|
|
||||||
count++;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
DEBUG_ShowMsg("DEBUG: Memory changed.");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
found = strstr(str,"INTT ");
|
found = strstr(str,"INTT ");
|
||||||
if (found) { // Create Cpu log file
|
if (found) { // Create Cpu log file
|
||||||
found+=4;
|
found+=4;
|
||||||
@ -1433,6 +1437,7 @@ Bitu DEBUG_Loop(void) {
|
|||||||
Bit16u oldCS = SegValue(cs);
|
Bit16u oldCS = SegValue(cs);
|
||||||
Bit32u oldEIP = reg_eip;
|
Bit32u oldEIP = reg_eip;
|
||||||
PIC_runIRQs();
|
PIC_runIRQs();
|
||||||
|
SDL_Delay(1);
|
||||||
if ((oldCS!=SegValue(cs)) || (oldEIP!=reg_eip)) {
|
if ((oldCS!=SegValue(cs)) || (oldEIP!=reg_eip)) {
|
||||||
CBreakpoint::AddBreakpoint(oldCS,oldEIP,true);
|
CBreakpoint::AddBreakpoint(oldCS,oldEIP,true);
|
||||||
CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip,true);
|
CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip,true);
|
||||||
@ -1455,13 +1460,14 @@ void DEBUG_DrawScreen(void) {
|
|||||||
DrawData();
|
DrawData();
|
||||||
DrawCode();
|
DrawCode();
|
||||||
DrawRegisters();
|
DrawRegisters();
|
||||||
|
DrawVariables();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DEBUG_RaiseTimerIrq(void) {
|
static void DEBUG_RaiseTimerIrq(void) {
|
||||||
PIC_ActivateIRQ(0);
|
PIC_ActivateIRQ(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogGDT(void)
|
static void LogGDT(void)
|
||||||
{
|
{
|
||||||
char out1[512];
|
char out1[512];
|
||||||
Descriptor desc;
|
Descriptor desc;
|
||||||
@ -1480,7 +1486,7 @@ void LogGDT(void)
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
void LogLDT(void)
|
static void LogLDT(void)
|
||||||
{
|
{
|
||||||
char out1[512];
|
char out1[512];
|
||||||
Descriptor desc;
|
Descriptor desc;
|
||||||
@ -1501,7 +1507,7 @@ void LogLDT(void)
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
void LogIDT(void)
|
static void LogIDT(void)
|
||||||
{
|
{
|
||||||
char out1[512];
|
char out1[512];
|
||||||
Descriptor desc;
|
Descriptor desc;
|
||||||
@ -1681,8 +1687,7 @@ void DEBUG_Init(Section* sec) {
|
|||||||
MSG_Add("DEBUG_CONFIGFILE_HELP","Nothing to setup yet!\n");
|
MSG_Add("DEBUG_CONFIGFILE_HELP","Nothing to setup yet!\n");
|
||||||
DEBUG_DrawScreen();
|
DEBUG_DrawScreen();
|
||||||
/* Add some keyhandlers */
|
/* Add some keyhandlers */
|
||||||
KEYBOARD_AddEvent(KBD_kpminus,0,DEBUG_Enable);
|
MAPPER_AddHandler(DEBUG_Enable,MK_pause,0,"debugger","Debugger");
|
||||||
KEYBOARD_AddEvent(KBD_kpplus,0,DEBUG_RaiseTimerIrq);
|
|
||||||
/* Clear the TBreakpoint list */
|
/* Clear the TBreakpoint list */
|
||||||
memset((void*)&codeViewData,0,sizeof(codeViewData));
|
memset((void*)&codeViewData,0,sizeof(codeViewData));
|
||||||
/* setup debug.com */
|
/* setup debug.com */
|
||||||
@ -1769,7 +1774,7 @@ bool CDebugVar::LoadVars(char* name)
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
void SaveMemory(Bitu seg, Bitu ofs1, Bit32s num)
|
static void SaveMemory(Bitu seg, Bitu ofs1, Bit32s num)
|
||||||
{
|
{
|
||||||
FILE* f = fopen("MEMDUMP.TXT","wt");
|
FILE* f = fopen("MEMDUMP.TXT","wt");
|
||||||
if (!f) {
|
if (!f) {
|
||||||
@ -1796,7 +1801,7 @@ void SaveMemory(Bitu seg, Bitu ofs1, Bit32s num)
|
|||||||
DEBUG_ShowMsg("DEBUG: Memory dump success.");
|
DEBUG_ShowMsg("DEBUG: Memory dump success.");
|
||||||
};
|
};
|
||||||
|
|
||||||
void OutputVecTable(char* filename)
|
static void OutputVecTable(char* filename)
|
||||||
{
|
{
|
||||||
FILE* f = fopen(filename, "wt");
|
FILE* f = fopen(filename, "wt");
|
||||||
if (!f)
|
if (!f)
|
||||||
@ -1812,6 +1817,35 @@ void OutputVecTable(char* filename)
|
|||||||
DEBUG_ShowMsg("DEBUG: Interrupt vector table written to %s.", filename);
|
DEBUG_ShowMsg("DEBUG: Interrupt vector table written to %s.", filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define DEBUG_VAR_BUF_LEN 16
|
||||||
|
static void DrawVariables(void)
|
||||||
|
{
|
||||||
|
std::list<CDebugVar*>::iterator i;
|
||||||
|
CDebugVar *dv;
|
||||||
|
char buffer[DEBUG_VAR_BUF_LEN];
|
||||||
|
|
||||||
|
int idx = 0;
|
||||||
|
for(i=CDebugVar::varList.begin(); i != CDebugVar::varList.end(); i++, idx++) {
|
||||||
|
|
||||||
|
if (idx == 4*3) {
|
||||||
|
/* too many variables */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
dv = static_cast<CDebugVar*>(*i);
|
||||||
|
|
||||||
|
Bit16u value = mem_readw(dv->GetAdr());
|
||||||
|
snprintf(buffer,DEBUG_VAR_BUF_LEN, "0x%04x", value);
|
||||||
|
|
||||||
|
int y = idx / 3;
|
||||||
|
int x = (idx % 3) * 26;
|
||||||
|
mvwprintw(dbg.win_var, y, x, dv->GetName());
|
||||||
|
mvwprintw(dbg.win_var, y, (x + DEBUG_VAR_BUF_LEN + 1) , buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
wrefresh(dbg.win_var);
|
||||||
|
}
|
||||||
|
#undef DEBUG_VAR_BUF_LEN
|
||||||
// HEAVY DEBUGGING STUFF
|
// HEAVY DEBUGGING STUFF
|
||||||
|
|
||||||
#if C_HEAVY_DEBUG
|
#if C_HEAVY_DEBUG
|
||||||
@ -1892,9 +1926,9 @@ bool DEBUG_HeavyIsBreakpoint(void)
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // HEAVY DEBUG
|
#endif // HEAVY DEBUG
|
||||||
|
|
||||||
|
|
||||||
#endif // DEBUG
|
#endif // DEBUG
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
@ -99,13 +99,15 @@ static void DrawBars(void) {
|
|||||||
attrset(COLOR_PAIR(PAIR_BLACK_BLUE));
|
attrset(COLOR_PAIR(PAIR_BLACK_BLUE));
|
||||||
}
|
}
|
||||||
/* Show the Register bar */
|
/* Show the Register bar */
|
||||||
mvaddstr(dbg.win_reg->_begy-1,0,"---[F1](Register Overview)---");
|
mvaddstr(dbg.win_reg->_begy-1,0,"---(Register Overview)---");
|
||||||
/* Show the Data Overview bar perhaps with more special stuff in the end */
|
/* Show the Data Overview bar perhaps with more special stuff in the end */
|
||||||
mvaddstr(dbg.win_data->_begy-1,0,"---[F2](Data Overview)---");
|
mvaddstr(dbg.win_data->_begy-1,0,"---(Data Overview)---");
|
||||||
/* Show the Code Overview perhaps with special stuff in bar too */
|
/* Show the Code Overview perhaps with special stuff in bar too */
|
||||||
mvaddstr(dbg.win_code->_begy-1,0,"---[F3](Code Overview)---");
|
mvaddstr(dbg.win_code->_begy-1,0,"---(Code Overview)---");
|
||||||
|
/* Show the Variable Overview bar */
|
||||||
|
mvaddstr(dbg.win_var->_begy-1,0,"---(Variable Overview)---");
|
||||||
/* Show the Output OverView */
|
/* Show the Output OverView */
|
||||||
mvaddstr(dbg.win_out->_begy-1,0,"---[F4](OutPut/Input)---");
|
mvaddstr(dbg.win_out->_begy-1,0,"---(OutPut/Input)---");
|
||||||
attrset(0);
|
attrset(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +126,10 @@ static void MakeSubWindows(void) {
|
|||||||
/* The Code Window */
|
/* The Code Window */
|
||||||
dbg.win_code=subwin(dbg.win_main,11,dbg.win_main->_maxx,outy,0);
|
dbg.win_code=subwin(dbg.win_main,11,dbg.win_main->_maxx,outy,0);
|
||||||
outy+=12;
|
outy+=12;
|
||||||
/* The output Window */
|
/* The Variable Window */
|
||||||
|
dbg.win_var=subwin(dbg.win_main,4,dbg.win_main->_maxx,outy,0);
|
||||||
|
outy+=5;
|
||||||
|
/* The Output Window */
|
||||||
dbg.win_out=subwin(dbg.win_main,dbg.win_main->_maxy-outy-1,dbg.win_main->_maxx,outy,0);
|
dbg.win_out=subwin(dbg.win_main,dbg.win_main->_maxy-outy-1,dbg.win_main->_maxx,outy,0);
|
||||||
dbg.input_y=dbg.win_main->_maxy-1;
|
dbg.input_y=dbg.win_main->_maxy-1;
|
||||||
scrollok(dbg.win_out,TRUE);
|
scrollok(dbg.win_out,TRUE);
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
@ -17,6 +17,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/* Local Debug Function */
|
/* Local Debug Function */
|
||||||
|
|
||||||
|
/* $Id: debug_inc.h,v 1.8 2004/08/28 12:51:35 qbix79 Exp $ */
|
||||||
|
|
||||||
#include <curses.h>
|
#include <curses.h>
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
|
|
||||||
@ -34,6 +37,7 @@ struct DBGBlock {
|
|||||||
WINDOW * win_reg; /* Register Window */
|
WINDOW * win_reg; /* Register Window */
|
||||||
WINDOW * win_data; /* Data Output window */
|
WINDOW * win_data; /* Data Output window */
|
||||||
WINDOW * win_code; /* Disassembly/Debug point Window */
|
WINDOW * win_code; /* Disassembly/Debug point Window */
|
||||||
|
WINDOW * win_var; /* Variable Window */
|
||||||
WINDOW * win_out; /* Text Output Window */
|
WINDOW * win_out; /* Text Output Window */
|
||||||
Bit32u active_win; /* Current active window */
|
Bit32u active_win; /* Current active window */
|
||||||
Bit32u input_y;
|
Bit32u input_y;
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
|
@ -4,6 +4,6 @@ noinst_LIBRARIES = libdos.a
|
|||||||
EXTRA_DIST = 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 \
|
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 \
|
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 \
|
drives.cpp drives.h drive_virtual.cpp drive_local.cpp drive_cache.cpp drive_fat.cpp \
|
||||||
dev_con.h dos_mscdex.cpp \
|
drive_iso.cpp dev_con.h dos_mscdex.cpp \
|
||||||
cdrom.h cdrom.cpp cdrom_ioctl_win32.cpp cdrom_aspi_win32.cpp cdrom_ioctl_linux.cpp
|
cdrom.h cdrom.cpp cdrom_ioctl_win32.cpp cdrom_aspi_win32.cpp cdrom_ioctl_linux.cpp cdrom_image.cpp
|
||||||
|
@ -135,9 +135,9 @@ noinst_LIBRARIES = libdos.a
|
|||||||
EXTRA_DIST = 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 \
|
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 \
|
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 \
|
drives.cpp drives.h drive_virtual.cpp drive_local.cpp drive_cache.cpp drive_fat.cpp \
|
||||||
dev_con.h dos_mscdex.cpp \
|
drive_iso.cpp dev_con.h dos_mscdex.cpp \
|
||||||
cdrom.h cdrom.cpp cdrom_ioctl_win32.cpp cdrom_aspi_win32.cpp cdrom_ioctl_linux.cpp
|
cdrom.h cdrom.cpp cdrom_ioctl_win32.cpp cdrom_aspi_win32.cpp cdrom_ioctl_linux.cpp cdrom_image.cpp
|
||||||
|
|
||||||
subdir = src/dos
|
subdir = src/dos
|
||||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||||
@ -153,9 +153,10 @@ am_libdos_a_OBJECTS = dos.$(OBJEXT) dos_devices.$(OBJEXT) \
|
|||||||
dos_memory.$(OBJEXT) dos_misc.$(OBJEXT) dos_classes.$(OBJEXT) \
|
dos_memory.$(OBJEXT) dos_misc.$(OBJEXT) dos_classes.$(OBJEXT) \
|
||||||
dos_programs.$(OBJEXT) dos_tables.$(OBJEXT) drives.$(OBJEXT) \
|
dos_programs.$(OBJEXT) dos_tables.$(OBJEXT) drives.$(OBJEXT) \
|
||||||
drive_virtual.$(OBJEXT) drive_local.$(OBJEXT) \
|
drive_virtual.$(OBJEXT) drive_local.$(OBJEXT) \
|
||||||
drive_cache.$(OBJEXT) dos_mscdex.$(OBJEXT) cdrom.$(OBJEXT) \
|
drive_cache.$(OBJEXT) drive_fat.$(OBJEXT) drive_iso.$(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)
|
cdrom_ioctl_linux.$(OBJEXT) cdrom_image.$(OBJEXT)
|
||||||
libdos_a_OBJECTS = $(am_libdos_a_OBJECTS)
|
libdos_a_OBJECTS = $(am_libdos_a_OBJECTS)
|
||||||
|
|
||||||
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
|
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
|
||||||
@ -163,6 +164,7 @@ depcomp = $(SHELL) $(top_srcdir)/depcomp
|
|||||||
am__depfiles_maybe = depfiles
|
am__depfiles_maybe = depfiles
|
||||||
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/cdrom.Po \
|
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/cdrom.Po \
|
||||||
@AMDEP_TRUE@ ./$(DEPDIR)/cdrom_aspi_win32.Po \
|
@AMDEP_TRUE@ ./$(DEPDIR)/cdrom_aspi_win32.Po \
|
||||||
|
@AMDEP_TRUE@ ./$(DEPDIR)/cdrom_image.Po \
|
||||||
@AMDEP_TRUE@ ./$(DEPDIR)/cdrom_ioctl_linux.Po \
|
@AMDEP_TRUE@ ./$(DEPDIR)/cdrom_ioctl_linux.Po \
|
||||||
@AMDEP_TRUE@ ./$(DEPDIR)/cdrom_ioctl_win32.Po ./$(DEPDIR)/dos.Po \
|
@AMDEP_TRUE@ ./$(DEPDIR)/cdrom_ioctl_win32.Po ./$(DEPDIR)/dos.Po \
|
||||||
@AMDEP_TRUE@ ./$(DEPDIR)/dos_classes.Po \
|
@AMDEP_TRUE@ ./$(DEPDIR)/dos_classes.Po \
|
||||||
@ -172,8 +174,8 @@ am__depfiles_maybe = depfiles
|
|||||||
@AMDEP_TRUE@ ./$(DEPDIR)/dos_misc.Po ./$(DEPDIR)/dos_mscdex.Po \
|
@AMDEP_TRUE@ ./$(DEPDIR)/dos_misc.Po ./$(DEPDIR)/dos_mscdex.Po \
|
||||||
@AMDEP_TRUE@ ./$(DEPDIR)/dos_programs.Po \
|
@AMDEP_TRUE@ ./$(DEPDIR)/dos_programs.Po \
|
||||||
@AMDEP_TRUE@ ./$(DEPDIR)/dos_tables.Po \
|
@AMDEP_TRUE@ ./$(DEPDIR)/dos_tables.Po \
|
||||||
@AMDEP_TRUE@ ./$(DEPDIR)/drive_cache.Po \
|
@AMDEP_TRUE@ ./$(DEPDIR)/drive_cache.Po ./$(DEPDIR)/drive_fat.Po \
|
||||||
@AMDEP_TRUE@ ./$(DEPDIR)/drive_local.Po \
|
@AMDEP_TRUE@ ./$(DEPDIR)/drive_iso.Po ./$(DEPDIR)/drive_local.Po \
|
||||||
@AMDEP_TRUE@ ./$(DEPDIR)/drive_virtual.Po ./$(DEPDIR)/drives.Po
|
@AMDEP_TRUE@ ./$(DEPDIR)/drive_virtual.Po ./$(DEPDIR)/drives.Po
|
||||||
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||||
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
|
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
|
||||||
@ -215,6 +217,7 @@ distclean-compile:
|
|||||||
|
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdrom.Po@am__quote@
|
@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_aspi_win32.Po@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdrom_image.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_linux.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdrom_ioctl_win32.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.Po@am__quote@
|
||||||
@ -229,6 +232,8 @@ distclean-compile:
|
|||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dos_programs.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dos_programs.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dos_tables.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dos_tables.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drive_cache.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drive_cache.Po@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drive_fat.Po@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drive_iso.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drive_local.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drive_local.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drive_virtual.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drive_virtual.Po@am__quote@
|
||||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drives.Po@am__quote@
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drives.Po@am__quote@
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
@ -21,6 +21,11 @@
|
|||||||
// SDL CDROM
|
// SDL CDROM
|
||||||
// ******************************************************
|
// ******************************************************
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include "dosbox.h"
|
||||||
#include "SDL.h"
|
#include "SDL.h"
|
||||||
#include "support.h"
|
#include "support.h"
|
||||||
#include "cdrom.h"
|
#include "cdrom.h"
|
||||||
@ -175,7 +180,12 @@ int CDROM_GetMountType(char* path, int forceCD)
|
|||||||
cdName = SDL_CDName(i);
|
cdName = SDL_CDName(i);
|
||||||
if (strcmp(buffer,cdName)==0) return 0;
|
if (strcmp(buffer,cdName)==0) return 0;
|
||||||
};
|
};
|
||||||
// TODO: Detect ISO
|
|
||||||
|
// Detect ISO
|
||||||
|
struct stat file_stat;
|
||||||
|
stat(path, &file_stat);
|
||||||
|
if (S_ISREG(file_stat.st_mode)) return 1;
|
||||||
|
|
||||||
return 2;
|
return 2;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
140
src/dos/cdrom.h
140
src/dos/cdrom.h
@ -5,10 +5,17 @@
|
|||||||
#define MAX_ASPI_CDROM 5
|
#define MAX_ASPI_CDROM 5
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
#include "dosbox.h"
|
#include "dosbox.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
|
#include "mixer.h"
|
||||||
#include "SDL.h"
|
#include "SDL.h"
|
||||||
|
#include "SDL_thread.h"
|
||||||
|
|
||||||
|
#if defined(C_SDL_SOUND)
|
||||||
|
#include "SDL_sound.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define RAW_SECTOR_SIZE 2352
|
#define RAW_SECTOR_SIZE 2352
|
||||||
#define COOKED_SECTOR_SIZE 2048
|
#define COOKED_SECTOR_SIZE 2048
|
||||||
@ -46,26 +53,28 @@ public:
|
|||||||
virtual bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num) = 0;
|
virtual bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num) = 0;
|
||||||
|
|
||||||
virtual bool LoadUnloadMedia (bool unload) = 0;
|
virtual bool LoadUnloadMedia (bool unload) = 0;
|
||||||
|
|
||||||
|
virtual void InitNewMedia (void) {};
|
||||||
};
|
};
|
||||||
|
|
||||||
class CDROM_Interface_SDL : public CDROM_Interface
|
class CDROM_Interface_SDL : public CDROM_Interface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CDROM_Interface_SDL (void);
|
CDROM_Interface_SDL (void);
|
||||||
~CDROM_Interface_SDL (void);
|
virtual ~CDROM_Interface_SDL(void);
|
||||||
|
|
||||||
bool SetDevice (char* path, int forceCD);
|
virtual bool SetDevice (char* path, int forceCD);
|
||||||
bool GetUPC (unsigned char& attr, char* upc) { attr = 0; strcpy(upc,"UPC"); return true; };
|
virtual bool GetUPC (unsigned char& attr, char* upc) { attr = 0; strcpy(upc,"UPC"); return true; };
|
||||||
bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut);
|
virtual bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut);
|
||||||
bool GetAudioTrackInfo (int track, TMSF& start, unsigned char& attr);
|
virtual bool GetAudioTrackInfo (int track, TMSF& start, unsigned char& attr);
|
||||||
bool GetAudioSub (unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos);
|
virtual bool GetAudioSub (unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos);
|
||||||
bool GetAudioStatus (bool& playing, bool& pause);
|
virtual bool GetAudioStatus (bool& playing, bool& pause);
|
||||||
bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen);
|
virtual bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen);
|
||||||
bool PlayAudioSector (unsigned long start,unsigned long len);
|
virtual bool PlayAudioSector (unsigned long start,unsigned long len);
|
||||||
bool PauseAudio (bool resume);
|
virtual bool PauseAudio (bool resume);
|
||||||
bool StopAudio (void);
|
virtual bool StopAudio (void);
|
||||||
bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num) { return false; };
|
virtual bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num) { return false; };
|
||||||
bool LoadUnloadMedia (bool unload);
|
virtual bool LoadUnloadMedia (bool unload);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool Open (void);
|
bool Open (void);
|
||||||
@ -93,6 +102,106 @@ public:
|
|||||||
bool LoadUnloadMedia (bool unload) { return true; };
|
bool LoadUnloadMedia (bool unload) { return true; };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CDROM_Interface_Image : public CDROM_Interface
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
class TrackFile {
|
||||||
|
public:
|
||||||
|
virtual bool read(Bit8u *buffer, int seek, int count) = 0;
|
||||||
|
virtual int getLength() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BinaryFile : public TrackFile {
|
||||||
|
public:
|
||||||
|
BinaryFile(const char *filename, bool &error);
|
||||||
|
~BinaryFile();
|
||||||
|
bool read(Bit8u *buffer, int seek, int count);
|
||||||
|
int getLength();
|
||||||
|
private:
|
||||||
|
BinaryFile();
|
||||||
|
std::ifstream *file;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined(C_SDL_SOUND)
|
||||||
|
class AudioFile : public TrackFile {
|
||||||
|
public:
|
||||||
|
AudioFile(const char *filename, bool &error);
|
||||||
|
~AudioFile();
|
||||||
|
bool read(Bit8u *buffer, int seek, int count);
|
||||||
|
int getLength();
|
||||||
|
private:
|
||||||
|
AudioFile();
|
||||||
|
Sound_Sample *sample;
|
||||||
|
int lastCount;
|
||||||
|
int lastSeek;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct Track {
|
||||||
|
int number;
|
||||||
|
int attr;
|
||||||
|
int start;
|
||||||
|
int length;
|
||||||
|
int skip;
|
||||||
|
int sectorSize;
|
||||||
|
bool mode2;
|
||||||
|
TrackFile *file;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
CDROM_Interface_Image (Bit8u subUnit);
|
||||||
|
virtual ~CDROM_Interface_Image (void);
|
||||||
|
void InitNewMedia (void);
|
||||||
|
bool SetDevice (char* path, int forceCD);
|
||||||
|
bool GetUPC (unsigned char& attr, char* upc);
|
||||||
|
bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut);
|
||||||
|
bool GetAudioTrackInfo (int track, TMSF& start, unsigned char& attr);
|
||||||
|
bool GetAudioSub (unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos);
|
||||||
|
bool GetAudioStatus (bool& playing, bool& pause);
|
||||||
|
bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen);
|
||||||
|
bool PlayAudioSector (unsigned long start,unsigned long len);
|
||||||
|
bool PauseAudio (bool resume);
|
||||||
|
bool StopAudio (void);
|
||||||
|
bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num);
|
||||||
|
bool LoadUnloadMedia (bool unload);
|
||||||
|
bool ReadSector (Bit8u *buffer, bool raw, unsigned long sector);
|
||||||
|
|
||||||
|
static CDROM_Interface_Image* images[26];
|
||||||
|
|
||||||
|
private:
|
||||||
|
// player
|
||||||
|
static void CDAudioCallBack(Bitu len);
|
||||||
|
int GetTrack(int sector);
|
||||||
|
|
||||||
|
static struct imagePlayer {
|
||||||
|
CDROM_Interface_Image *cd;
|
||||||
|
MixerChannel *channel;
|
||||||
|
SDL_mutex *mutex;
|
||||||
|
Bit8u buffer[8192];
|
||||||
|
int bufLen;
|
||||||
|
int currFrame;
|
||||||
|
int targetFrame;
|
||||||
|
bool isPlaying;
|
||||||
|
bool isPaused;
|
||||||
|
} player;
|
||||||
|
|
||||||
|
void ClearTracks();
|
||||||
|
bool LoadIsoFile(char *filename);
|
||||||
|
bool CanReadPVD(TrackFile *file, int sectorSize, bool mode2);
|
||||||
|
// cue sheet processing
|
||||||
|
bool LoadCueSheet(char *cuefile);
|
||||||
|
bool GetRealFileName(std::string& filename, std::string& pathname);
|
||||||
|
bool GetCueKeyword(std::string &keyword, std::istream &in);
|
||||||
|
bool GetCueFrame(int &frames, std::istream &in);
|
||||||
|
bool GetCueString(std::string &str, std::istream &in);
|
||||||
|
bool AddTrack(Track &curr, int &shift, int prestart, int &totalPregap, int currPregap);
|
||||||
|
|
||||||
|
static int refCount;
|
||||||
|
std::vector<Track> tracks;
|
||||||
|
std::string mcn;
|
||||||
|
Bit8u subUnit;
|
||||||
|
};
|
||||||
|
|
||||||
#if defined (WIN32) /* Win 32 */
|
#if defined (WIN32) /* Win 32 */
|
||||||
|
|
||||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||||
@ -104,7 +213,7 @@ class CDROM_Interface_Aspi : public CDROM_Interface
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CDROM_Interface_Aspi (void);
|
CDROM_Interface_Aspi (void);
|
||||||
~CDROM_Interface_Aspi (void);
|
virtual ~CDROM_Interface_Aspi(void);
|
||||||
|
|
||||||
bool SetDevice (char* path, int forceCD);
|
bool SetDevice (char* path, int forceCD);
|
||||||
|
|
||||||
@ -151,7 +260,7 @@ class CDROM_Interface_Ioctl : public CDROM_Interface
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CDROM_Interface_Ioctl (void);
|
CDROM_Interface_Ioctl (void);
|
||||||
~CDROM_Interface_Ioctl (void);
|
virtual ~CDROM_Interface_Ioctl(void);
|
||||||
|
|
||||||
bool SetDevice (char* path, int forceCD);
|
bool SetDevice (char* path, int forceCD);
|
||||||
|
|
||||||
@ -171,6 +280,7 @@ public:
|
|||||||
|
|
||||||
bool LoadUnloadMedia (bool unload);
|
bool LoadUnloadMedia (bool unload);
|
||||||
|
|
||||||
|
void InitNewMedia (void) { Close(); Open(); };
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool Open (void);
|
bool Open (void);
|
||||||
|
@ -9,14 +9,14 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: cdrom_aspi_win32.cpp,v 1.10 2004/01/10 14:03:34 qbix79 Exp $ */
|
/* $Id: cdrom_aspi_win32.cpp,v 1.12 2004/08/04 09:12:53 qbix79 Exp $ */
|
||||||
|
|
||||||
#if defined (WIN32)
|
#if defined (WIN32)
|
||||||
|
|
||||||
@ -39,6 +39,19 @@
|
|||||||
|
|
||||||
#include "scsidefs.h"
|
#include "scsidefs.h"
|
||||||
|
|
||||||
|
// always use a buffer of the maximum struct size (like the union of all 'SRB_*' struct types)
|
||||||
|
// Thanx SaPu
|
||||||
|
typedef union {
|
||||||
|
SRB_HAInquiry hainquiry;
|
||||||
|
SRB_GDEVBlock gdevblock;
|
||||||
|
SRB_ExecSCSICmd execscsicmd;
|
||||||
|
SRB_Abort abort;
|
||||||
|
SRB_BusDeviceReset busdevicereset;
|
||||||
|
SRB_GetDiskInfo getdiskinfo;
|
||||||
|
SRB_RescanPort rescanport;
|
||||||
|
SRB_GetSetTimeouts getsettimeouts;
|
||||||
|
} ASPI_SRB;
|
||||||
|
|
||||||
// *****************************************************************
|
// *****************************************************************
|
||||||
// Windows ASPI functions (should work for all WIN with ASPI layer)
|
// Windows ASPI functions (should work for all WIN with ASPI layer)
|
||||||
// *****************************************************************
|
// *****************************************************************
|
||||||
@ -78,34 +91,34 @@ bool GetRegistryValue(HKEY& hKey,char* valueName, char* buffer, ULONG bufferSize
|
|||||||
|
|
||||||
BYTE CDROM_Interface_Aspi::GetHostAdapter(char* hardwareID)
|
BYTE CDROM_Interface_Aspi::GetHostAdapter(char* hardwareID)
|
||||||
{
|
{
|
||||||
SRB_HAInquiry sh;
|
ASPI_SRB sh;
|
||||||
SRB_GDEVBlock sd;
|
ASPI_SRB sd;
|
||||||
DWORD d = pGetASPI32SupportInfo();
|
DWORD d = pGetASPI32SupportInfo();
|
||||||
int cnt = LOBYTE(LOWORD(d));
|
int cnt = LOBYTE(LOWORD(d));
|
||||||
int i,j,k,max;
|
int i,j,k,max;
|
||||||
|
|
||||||
for(i=0; i<cnt; i++) {
|
for(i=0; i<cnt; i++) {
|
||||||
memset(&sh, 0, sizeof(sh));
|
memset(&sh, 0, sizeof(sh));
|
||||||
sh.SRB_Cmd = SC_HA_INQUIRY;
|
sh.hainquiry.SRB_Cmd = SC_HA_INQUIRY;
|
||||||
sh.SRB_HaId = i;
|
sh.hainquiry.SRB_HaId = i;
|
||||||
pSendASPI32Command((LPSRB)&sh);
|
pSendASPI32Command((LPSRB)&sh);
|
||||||
if (sh.SRB_Status!=SS_COMP) continue;
|
if (sh.hainquiry.SRB_Status!=SS_COMP) continue;
|
||||||
|
|
||||||
// Indicates the maximum number of targets the adapter supports
|
// Indicates the maximum number of targets the adapter supports
|
||||||
// If the value is not 8 or 16, then it should be assumed max target is 8
|
// If the value is not 8 or 16, then it should be assumed max target is 8
|
||||||
max = (int)sh.HA_Unique[3];
|
max = (int)sh.hainquiry.HA_Unique[3];
|
||||||
if ((max!=8) && (max!=16)) max = 8;
|
if ((max!=8) && (max!=16)) max = 8;
|
||||||
|
|
||||||
for(j=0; j<max; j++) {
|
for(j=0; j<max; j++) {
|
||||||
for(k=0; k<8; k++) {
|
for(k=0; k<8; k++) {
|
||||||
memset(&sd, 0, sizeof(sd));
|
memset(&sd, 0, sizeof(sd));
|
||||||
sd.SRB_Cmd = SC_GET_DEV_TYPE;
|
sd.gdevblock.SRB_Cmd = SC_GET_DEV_TYPE;
|
||||||
sd.SRB_HaId = i;
|
sd.gdevblock.SRB_HaId = i;
|
||||||
sd.SRB_Target = j;
|
sd.gdevblock.SRB_Target = j;
|
||||||
sd.SRB_Lun = k;
|
sd.gdevblock.SRB_Lun = k;
|
||||||
pSendASPI32Command((LPSRB)&sd);
|
pSendASPI32Command((LPSRB)&sd);
|
||||||
if (sd.SRB_Status == SS_COMP) {
|
if (sd.gdevblock.SRB_Status == SS_COMP) {
|
||||||
if (sd.SRB_DeviceType == DTYPE_CDROM) {
|
if (sd.gdevblock.SRB_DeviceType == DTYPE_CDROM) {
|
||||||
if ((target==j) && (lun==k)) {
|
if ((target==j) && (lun==k)) {
|
||||||
LOG(LOG_MISC,LOG_NORMAL)("SCSI: Getting Hardware vendor.");
|
LOG(LOG_MISC,LOG_NORMAL)("SCSI: Getting Hardware vendor.");
|
||||||
// "Hardware ID = vendor" match ?
|
// "Hardware ID = vendor" match ?
|
||||||
@ -175,23 +188,24 @@ bool CDROM_Interface_Aspi::ScanRegistryFindKey(HKEY& hKeyBase)
|
|||||||
|
|
||||||
bool CDROM_Interface_Aspi::GetVendor(BYTE HA_num, BYTE SCSI_Id, BYTE SCSI_Lun, char* szBuffer)
|
bool CDROM_Interface_Aspi::GetVendor(BYTE HA_num, BYTE SCSI_Id, BYTE SCSI_Lun, char* szBuffer)
|
||||||
{
|
{
|
||||||
SRB_ExecSCSICmd srbExec;
|
ASPI_SRB srbExec;
|
||||||
|
// SRB_ExecSCSICmd srbExec;
|
||||||
memset ( &srbExec, 0, sizeof ( SRB_ExecSCSICmd ) );
|
memset ( &srbExec, 0, sizeof ( SRB_ExecSCSICmd ) );
|
||||||
|
|
||||||
hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
||||||
|
|
||||||
srbExec.SRB_Cmd = SC_EXEC_SCSI_CMD ;
|
srbExec.execscsicmd.SRB_Cmd = SC_EXEC_SCSI_CMD ;
|
||||||
srbExec.SRB_HaId = HA_num;
|
srbExec.execscsicmd.SRB_HaId = HA_num;
|
||||||
srbExec.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
srbExec.execscsicmd.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
||||||
srbExec.SRB_Target = SCSI_Id;
|
srbExec.execscsicmd.SRB_Target = SCSI_Id;
|
||||||
srbExec.SRB_Lun = SCSI_Lun;
|
srbExec.execscsicmd.SRB_Lun = SCSI_Lun;
|
||||||
srbExec.SRB_BufLen = 36;
|
srbExec.execscsicmd.SRB_BufLen = 36;
|
||||||
srbExec.SRB_BufPointer = (unsigned char*)szBuffer;
|
srbExec.execscsicmd.SRB_BufPointer = (unsigned char*)szBuffer;
|
||||||
srbExec.SRB_SenseLen = SENSE_LEN;
|
srbExec.execscsicmd.SRB_SenseLen = SENSE_LEN;
|
||||||
srbExec.SRB_CDBLen = 6;
|
srbExec.execscsicmd.SRB_CDBLen = 6;
|
||||||
srbExec.SRB_PostProc = (LPVOID)hEvent;
|
srbExec.execscsicmd.SRB_PostProc = (LPVOID)hEvent;
|
||||||
srbExec.CDBByte [ 0 ] = SCSI_INQUIRY;
|
srbExec.execscsicmd.CDBByte [ 0 ] = SCSI_INQUIRY;
|
||||||
srbExec.CDBByte [ 4 ] = 36; // allocation length per szBuffer [ ]
|
srbExec.execscsicmd.CDBByte [ 4 ] = 36; // allocation length per szBuffer [ ]
|
||||||
|
|
||||||
ResetEvent(hEvent);
|
ResetEvent(hEvent);
|
||||||
int dwStatus = pSendASPI32Command ((LPSRB)&srbExec);
|
int dwStatus = pSendASPI32Command ((LPSRB)&srbExec);
|
||||||
@ -201,7 +215,7 @@ bool CDROM_Interface_Aspi::GetVendor(BYTE HA_num, BYTE SCSI_Id, BYTE SCSI_Lun, c
|
|||||||
// LOG(LOG_MISC|LOG_ERROR,"SCSI: Pending done.");
|
// LOG(LOG_MISC|LOG_ERROR,"SCSI: Pending done.");
|
||||||
|
|
||||||
CloseHandle(hEvent);
|
CloseHandle(hEvent);
|
||||||
if (srbExec.SRB_Status != SS_COMP) {
|
if (srbExec.execscsicmd.SRB_Status != SS_COMP) {
|
||||||
strcpy (szBuffer, "error" );
|
strcpy (szBuffer, "error" );
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
@ -373,26 +387,28 @@ void CDROM_Interface_Aspi::GetIOCTLAdapter(HANDLE hF,int * iDA,int * iDT,int * i
|
|||||||
|
|
||||||
DWORD CDROM_Interface_Aspi::GetTOC(LPTOC toc)
|
DWORD CDROM_Interface_Aspi::GetTOC(LPTOC toc)
|
||||||
{
|
{
|
||||||
SRB_ExecSCSICmd s;DWORD dwStatus;
|
// SRB_ExecSCSICmd s;
|
||||||
|
ASPI_SRB s;
|
||||||
|
DWORD dwStatus;
|
||||||
|
|
||||||
hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
||||||
|
|
||||||
memset(&s,0,sizeof(s));
|
memset(&s,0,sizeof(s));
|
||||||
|
|
||||||
s.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
s.execscsicmd.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
||||||
s.SRB_HaId = haId;
|
s.execscsicmd.SRB_HaId = haId;
|
||||||
s.SRB_Target = target;
|
s.execscsicmd.SRB_Target = target;
|
||||||
s.SRB_Lun = lun;
|
s.execscsicmd.SRB_Lun = lun;
|
||||||
s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
s.execscsicmd.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
||||||
s.SRB_BufLen = sizeof(*toc);
|
s.execscsicmd.SRB_BufLen = sizeof(*toc);
|
||||||
s.SRB_BufPointer = (BYTE FAR *)toc;
|
s.execscsicmd.SRB_BufPointer = (BYTE FAR *)toc;
|
||||||
s.SRB_SenseLen = SENSE_LEN;
|
s.execscsicmd.SRB_SenseLen = SENSE_LEN;
|
||||||
s.SRB_CDBLen = 0x0A;
|
s.execscsicmd.SRB_CDBLen = 0x0A;
|
||||||
s.SRB_PostProc = (LPVOID)hEvent;
|
s.execscsicmd.SRB_PostProc = (LPVOID)hEvent;
|
||||||
s.CDBByte[0] = SCSI_READ_TOC;
|
s.execscsicmd.CDBByte[0] = SCSI_READ_TOC;
|
||||||
s.CDBByte[1] = 0x02; // 0x02 for MSF
|
s.execscsicmd.CDBByte[1] = 0x02; // 0x02 for MSF
|
||||||
s.CDBByte[7] = 0x03;
|
s.execscsicmd.CDBByte[7] = 0x03;
|
||||||
s.CDBByte[8] = 0x24;
|
s.execscsicmd.CDBByte[8] = 0x24;
|
||||||
|
|
||||||
ResetEvent(hEvent);
|
ResetEvent(hEvent);
|
||||||
dwStatus=pSendASPI32Command((LPSRB)&s);
|
dwStatus=pSendASPI32Command((LPSRB)&s);
|
||||||
@ -401,37 +417,39 @@ DWORD CDROM_Interface_Aspi::GetTOC(LPTOC toc)
|
|||||||
|
|
||||||
CloseHandle(hEvent);
|
CloseHandle(hEvent);
|
||||||
|
|
||||||
return (s.SRB_Status==SS_COMP);
|
return (s.execscsicmd.SRB_Status==SS_COMP);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CDROM_Interface_Aspi::PlayAudioSector(unsigned long start,unsigned long len)
|
bool CDROM_Interface_Aspi::PlayAudioSector(unsigned long start,unsigned long len)
|
||||||
{
|
{
|
||||||
SRB_ExecSCSICmd s;DWORD dwStatus;
|
// SRB_ExecSCSICmd s;
|
||||||
|
ASPI_SRB s;
|
||||||
|
DWORD dwStatus;
|
||||||
|
|
||||||
hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
||||||
|
|
||||||
memset(&s,0,sizeof(s));
|
memset(&s,0,sizeof(s));
|
||||||
s.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
s.execscsicmd.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
||||||
s.SRB_HaId = haId;
|
s.execscsicmd.SRB_HaId = haId;
|
||||||
s.SRB_Target = target;
|
s.execscsicmd.SRB_Target = target;
|
||||||
s.SRB_Lun = lun;
|
s.execscsicmd.SRB_Lun = lun;
|
||||||
s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
s.execscsicmd.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
||||||
s.SRB_BufLen = 0;
|
s.execscsicmd.SRB_BufLen = 0;
|
||||||
s.SRB_BufPointer = 0;
|
s.execscsicmd.SRB_BufPointer = 0;
|
||||||
s.SRB_SenseLen = SENSE_LEN;
|
s.execscsicmd.SRB_SenseLen = SENSE_LEN;
|
||||||
s.SRB_CDBLen = 12;
|
s.execscsicmd.SRB_CDBLen = 12;
|
||||||
s.SRB_PostProc = (LPVOID)hEvent;
|
s.execscsicmd.SRB_PostProc = (LPVOID)hEvent;
|
||||||
|
|
||||||
s.CDBByte[0] = SCSI_PLAYAUD_12;
|
s.execscsicmd.CDBByte[0] = SCSI_PLAYAUD_12;
|
||||||
s.CDBByte[1] = lun << 5;
|
s.execscsicmd.CDBByte[1] = lun << 5;
|
||||||
s.CDBByte[2] = (unsigned char)((start >> 24) & 0xFF);
|
s.execscsicmd.CDBByte[2] = (unsigned char)((start >> 24) & 0xFF);
|
||||||
s.CDBByte[3] = (unsigned char)((start >> 16) & 0xFF);
|
s.execscsicmd.CDBByte[3] = (unsigned char)((start >> 16) & 0xFF);
|
||||||
s.CDBByte[4] = (unsigned char)((start >> 8) & 0xFF);
|
s.execscsicmd.CDBByte[4] = (unsigned char)((start >> 8) & 0xFF);
|
||||||
s.CDBByte[5] = (unsigned char)((start & 0xFF));
|
s.execscsicmd.CDBByte[5] = (unsigned char)((start & 0xFF));
|
||||||
s.CDBByte[6] = (unsigned char)((len >> 24) & 0xFF);
|
s.execscsicmd.CDBByte[6] = (unsigned char)((len >> 24) & 0xFF);
|
||||||
s.CDBByte[7] = (unsigned char)((len >> 16) & 0xFF);
|
s.execscsicmd.CDBByte[7] = (unsigned char)((len >> 16) & 0xFF);
|
||||||
s.CDBByte[8] = (unsigned char)((len >> 8) & 0xFF);
|
s.execscsicmd.CDBByte[8] = (unsigned char)((len >> 8) & 0xFF);
|
||||||
s.CDBByte[9] = (unsigned char)(len & 0xFF);
|
s.execscsicmd.CDBByte[9] = (unsigned char)(len & 0xFF);
|
||||||
|
|
||||||
ResetEvent(hEvent);
|
ResetEvent(hEvent);
|
||||||
|
|
||||||
@ -441,7 +459,7 @@ bool CDROM_Interface_Aspi::PlayAudioSector(unsigned long start,unsigned long len
|
|||||||
|
|
||||||
CloseHandle(hEvent);
|
CloseHandle(hEvent);
|
||||||
|
|
||||||
return s.SRB_Status==SS_COMP;
|
return s.execscsicmd.SRB_Status==SS_COMP;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CDROM_Interface_Aspi::StopAudio(void)
|
bool CDROM_Interface_Aspi::StopAudio(void)
|
||||||
@ -451,23 +469,25 @@ bool CDROM_Interface_Aspi::StopAudio(void)
|
|||||||
|
|
||||||
bool CDROM_Interface_Aspi::PauseAudio(bool resume)
|
bool CDROM_Interface_Aspi::PauseAudio(bool resume)
|
||||||
{
|
{
|
||||||
SRB_ExecSCSICmd s;DWORD dwStatus;
|
//SRB_ExecSCSICmd s;
|
||||||
|
ASPI_SRB s;
|
||||||
|
DWORD dwStatus;
|
||||||
|
|
||||||
hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
||||||
|
|
||||||
memset(&s,0,sizeof(s));
|
memset(&s,0,sizeof(s));
|
||||||
|
|
||||||
s.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
s.execscsicmd.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
||||||
s.SRB_HaId = haId;
|
s.execscsicmd.SRB_HaId = haId;
|
||||||
s.SRB_Target = target;
|
s.execscsicmd.SRB_Target = target;
|
||||||
s.SRB_Lun = lun;
|
s.execscsicmd.SRB_Lun = lun;
|
||||||
s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
s.execscsicmd.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
||||||
s.SRB_BufLen = 0x00;
|
s.execscsicmd.SRB_BufLen = 0x00;
|
||||||
s.SRB_SenseLen = SENSE_LEN;
|
s.execscsicmd.SRB_SenseLen = SENSE_LEN;
|
||||||
s.SRB_CDBLen = 0x0A;
|
s.execscsicmd.SRB_CDBLen = 0x0A;
|
||||||
s.SRB_PostProc = (LPVOID)hEvent;
|
s.execscsicmd.SRB_PostProc = (LPVOID)hEvent;
|
||||||
s.CDBByte[0] = 0x4B;
|
s.execscsicmd.CDBByte[0] = 0x4B;
|
||||||
s.CDBByte[8] = (unsigned char)resume; // Pause
|
s.execscsicmd.CDBByte[8] = (unsigned char)resume; // Pause
|
||||||
|
|
||||||
ResetEvent(hEvent);
|
ResetEvent(hEvent);
|
||||||
dwStatus=pSendASPI32Command((LPSRB)&s);
|
dwStatus=pSendASPI32Command((LPSRB)&s);
|
||||||
@ -476,37 +496,39 @@ bool CDROM_Interface_Aspi::PauseAudio(bool resume)
|
|||||||
|
|
||||||
CloseHandle(hEvent);
|
CloseHandle(hEvent);
|
||||||
|
|
||||||
return (s.SRB_Status==SS_COMP);
|
return (s.execscsicmd.SRB_Status==SS_COMP);
|
||||||
};
|
};
|
||||||
|
|
||||||
bool CDROM_Interface_Aspi::GetAudioSub(unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos)
|
bool CDROM_Interface_Aspi::GetAudioSub(unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos)
|
||||||
{
|
{
|
||||||
SUB_Q_CURRENT_POSITION pos;
|
SUB_Q_CURRENT_POSITION pos;
|
||||||
SRB_ExecSCSICmd s;DWORD dwStatus;
|
// SRB_ExecSCSICmd s;
|
||||||
|
ASPI_SRB s;
|
||||||
|
DWORD dwStatus;
|
||||||
|
|
||||||
hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
||||||
|
|
||||||
memset(&s,0,sizeof(s));
|
memset(&s,0,sizeof(s));
|
||||||
|
|
||||||
s.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
s.execscsicmd.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
||||||
s.SRB_HaId = haId;
|
s.execscsicmd.SRB_HaId = haId;
|
||||||
s.SRB_Target = target;
|
s.execscsicmd.SRB_Target = target;
|
||||||
s.SRB_Lun = lun;
|
s.execscsicmd.SRB_Lun = lun;
|
||||||
s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
s.execscsicmd.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
||||||
s.SRB_SenseLen = SENSE_LEN;
|
s.execscsicmd.SRB_SenseLen = SENSE_LEN;
|
||||||
|
|
||||||
s.SRB_BufLen = sizeof(pos);
|
s.execscsicmd.SRB_BufLen = sizeof(pos);
|
||||||
s.SRB_BufPointer = (BYTE FAR *)&pos;
|
s.execscsicmd.SRB_BufPointer = (BYTE FAR *)&pos;
|
||||||
s.SRB_CDBLen = 10;
|
s.execscsicmd.SRB_CDBLen = 10;
|
||||||
s.SRB_PostProc = (LPVOID)hEvent;
|
s.execscsicmd.SRB_PostProc = (LPVOID)hEvent;
|
||||||
|
|
||||||
s.CDBByte[0] = SCSI_SUBCHANNEL;
|
s.execscsicmd.CDBByte[0] = SCSI_SUBCHANNEL;
|
||||||
s.CDBByte[1] = (lun<<5)|2; // lun & msf
|
s.execscsicmd.CDBByte[1] = (lun<<5)|2; // lun & msf
|
||||||
s.CDBByte[2] = 0x40; // subq
|
s.execscsicmd.CDBByte[2] = 0x40; // subq
|
||||||
s.CDBByte[3] = 0x01; // curr pos info
|
s.execscsicmd.CDBByte[3] = 0x01; // curr pos info
|
||||||
s.CDBByte[6] = 0; // track number (only in isrc mode, ignored)
|
s.execscsicmd.CDBByte[6] = 0; // track number (only in isrc mode, ignored)
|
||||||
s.CDBByte[7] = 0; // alloc len
|
s.execscsicmd.CDBByte[7] = 0; // alloc len
|
||||||
s.CDBByte[8] = sizeof(pos);
|
s.execscsicmd.CDBByte[8] = sizeof(pos);
|
||||||
|
|
||||||
ResetEvent(hEvent);
|
ResetEvent(hEvent);
|
||||||
|
|
||||||
@ -516,7 +538,7 @@ bool CDROM_Interface_Aspi::GetAudioSub(unsigned char& attr, unsigned char& track
|
|||||||
|
|
||||||
CloseHandle(hEvent);
|
CloseHandle(hEvent);
|
||||||
|
|
||||||
if (s.SRB_Status!=SS_COMP) return false;
|
if (s.execscsicmd.SRB_Status!=SS_COMP) return false;
|
||||||
|
|
||||||
attr = (pos.Control<<4) &0xEF;
|
attr = (pos.Control<<4) &0xEF;
|
||||||
track = pos.TrackNumber;
|
track = pos.TrackNumber;
|
||||||
@ -534,31 +556,33 @@ bool CDROM_Interface_Aspi::GetAudioSub(unsigned char& attr, unsigned char& track
|
|||||||
bool CDROM_Interface_Aspi::GetUPC(unsigned char& attr, char* upcdata)
|
bool CDROM_Interface_Aspi::GetUPC(unsigned char& attr, char* upcdata)
|
||||||
{
|
{
|
||||||
SUB_Q_MEDIA_CATALOG_NUMBER upc;
|
SUB_Q_MEDIA_CATALOG_NUMBER upc;
|
||||||
SRB_ExecSCSICmd s;DWORD dwStatus;
|
ASPI_SRB s;
|
||||||
|
//SRB_ExecSCSICmd s;
|
||||||
|
DWORD dwStatus;
|
||||||
|
|
||||||
hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
||||||
|
|
||||||
memset(&s,0,sizeof(s));
|
memset(&s,0,sizeof(s));
|
||||||
|
|
||||||
s.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
s.execscsicmd.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
||||||
s.SRB_HaId = haId;
|
s.execscsicmd.SRB_HaId = haId;
|
||||||
s.SRB_Target = target;
|
s.execscsicmd.SRB_Target = target;
|
||||||
s.SRB_Lun = lun;
|
s.execscsicmd.SRB_Lun = lun;
|
||||||
s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
s.execscsicmd.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
||||||
s.SRB_SenseLen = SENSE_LEN;
|
s.execscsicmd.SRB_SenseLen = SENSE_LEN;
|
||||||
|
|
||||||
s.SRB_BufLen = sizeof(upc);
|
s.execscsicmd.SRB_BufLen = sizeof(upc);
|
||||||
s.SRB_BufPointer = (BYTE FAR *)&upc;
|
s.execscsicmd.SRB_BufPointer = (BYTE FAR *)&upc;
|
||||||
s.SRB_CDBLen = 10;
|
s.execscsicmd.SRB_CDBLen = 10;
|
||||||
s.SRB_PostProc = (LPVOID)hEvent;
|
s.execscsicmd.SRB_PostProc = (LPVOID)hEvent;
|
||||||
|
|
||||||
s.CDBByte[0] = SCSI_SUBCHANNEL;
|
s.execscsicmd.CDBByte[0] = SCSI_SUBCHANNEL;
|
||||||
s.CDBByte[1] = (lun<<5)|2; // lun & msf
|
s.execscsicmd.CDBByte[1] = (lun<<5)|2; // lun & msf
|
||||||
s.CDBByte[2] = 0x40; // subq
|
s.execscsicmd.CDBByte[2] = 0x40; // subq
|
||||||
s.CDBByte[3] = 0x02; // get upc
|
s.execscsicmd.CDBByte[3] = 0x02; // get upc
|
||||||
s.CDBByte[6] = 0; // track number (only in isrc mode, ignored)
|
s.execscsicmd.CDBByte[6] = 0; // track number (only in isrc mode, ignored)
|
||||||
s.CDBByte[7] = 0; // alloc len
|
s.execscsicmd.CDBByte[7] = 0; // alloc len
|
||||||
s.CDBByte[8] = sizeof(upc);
|
s.execscsicmd.CDBByte[8] = sizeof(upc);
|
||||||
|
|
||||||
ResetEvent(hEvent);
|
ResetEvent(hEvent);
|
||||||
|
|
||||||
@ -568,15 +592,14 @@ bool CDROM_Interface_Aspi::GetUPC(unsigned char& attr, char* upcdata)
|
|||||||
|
|
||||||
CloseHandle(hEvent);
|
CloseHandle(hEvent);
|
||||||
|
|
||||||
if (s.SRB_Status!=SS_COMP) return false;
|
if (s.execscsicmd.SRB_Status!=SS_COMP) return false;
|
||||||
|
|
||||||
// attr = (upc.ADR<<4) | upc.Control;
|
// attr = (upc.ADR<<4) | upc.Control;
|
||||||
attr = 0;
|
attr = 0;
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
// Convert to mscdex format
|
// Convert to mscdex format
|
||||||
// for (int i=0; i<6; i++) upcdata[i] = (upc.MediaCatalog[pos++]<<4)+(upc.MediaCatalog[pos++]&0x0F);
|
|
||||||
// upcdata[6] = (upc.MediaCatalog[pos++]<<4);
|
|
||||||
for (int i=0; i<7; i++) upcdata[i] = upc.MediaCatalog[i];
|
for (int i=0; i<7; i++) upcdata[i] = upc.MediaCatalog[i];
|
||||||
|
for (int i=0; i<7; i++) upcdata[i] = (upc.MediaCatalog[i*2] << 4) | (upc.MediaCatalog[i*2+1] & 0x0F);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
@ -586,31 +609,33 @@ bool CDROM_Interface_Aspi::GetAudioStatus(bool& playing, bool& pause)
|
|||||||
playing = pause = false;
|
playing = pause = false;
|
||||||
|
|
||||||
SUB_Q_HEADER sub;
|
SUB_Q_HEADER sub;
|
||||||
SRB_ExecSCSICmd s;DWORD dwStatus;
|
// SRB_ExecSCSICmd s;
|
||||||
|
ASPI_SRB s;
|
||||||
|
DWORD dwStatus;
|
||||||
|
|
||||||
hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
||||||
|
|
||||||
memset(&s,0,sizeof(s));
|
memset(&s,0,sizeof(s));
|
||||||
|
|
||||||
s.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
s.execscsicmd.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
||||||
s.SRB_HaId = haId;
|
s.execscsicmd.SRB_HaId = haId;
|
||||||
s.SRB_Target = target;
|
s.execscsicmd.SRB_Target = target;
|
||||||
s.SRB_Lun = lun;
|
s.execscsicmd.SRB_Lun = lun;
|
||||||
s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
s.execscsicmd.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
||||||
s.SRB_SenseLen = SENSE_LEN;
|
s.execscsicmd.SRB_SenseLen = SENSE_LEN;
|
||||||
|
|
||||||
s.SRB_BufLen = sizeof(sub);
|
s.execscsicmd.SRB_BufLen = sizeof(sub);
|
||||||
s.SRB_BufPointer = (BYTE FAR *)⊂
|
s.execscsicmd.SRB_BufPointer = (BYTE FAR *)⊂
|
||||||
s.SRB_CDBLen = 10;
|
s.execscsicmd.SRB_CDBLen = 10;
|
||||||
s.SRB_PostProc = (LPVOID)hEvent;
|
s.execscsicmd.SRB_PostProc = (LPVOID)hEvent;
|
||||||
|
|
||||||
s.CDBByte[0] = SCSI_SUBCHANNEL;
|
s.execscsicmd.CDBByte[0] = SCSI_SUBCHANNEL;
|
||||||
s.CDBByte[1] = (lun<<5)|2; // lun & msf
|
s.execscsicmd.CDBByte[1] = (lun<<5)|2; // lun & msf
|
||||||
s.CDBByte[2] = 0x00; // no subq
|
s.execscsicmd.CDBByte[2] = 0x00; // no subq
|
||||||
s.CDBByte[3] = 0x00; // dont care
|
s.execscsicmd.CDBByte[3] = 0x00; // dont care
|
||||||
s.CDBByte[6] = 0; // track number (only in isrc mode, ignored)
|
s.execscsicmd.CDBByte[6] = 0; // track number (only in isrc mode, ignored)
|
||||||
s.CDBByte[7] = 0; // alloc len
|
s.execscsicmd.CDBByte[7] = 0; // alloc len
|
||||||
s.CDBByte[8] = sizeof(sub);
|
s.execscsicmd.CDBByte[8] = sizeof(sub);
|
||||||
|
|
||||||
ResetEvent(hEvent);
|
ResetEvent(hEvent);
|
||||||
|
|
||||||
@ -620,7 +645,7 @@ bool CDROM_Interface_Aspi::GetAudioStatus(bool& playing, bool& pause)
|
|||||||
|
|
||||||
CloseHandle(hEvent);
|
CloseHandle(hEvent);
|
||||||
|
|
||||||
if (s.SRB_Status!=SS_COMP) return false;
|
if (s.execscsicmd.SRB_Status!=SS_COMP) return false;
|
||||||
|
|
||||||
playing = (sub.AudioStatus==0x11);
|
playing = (sub.AudioStatus==0x11);
|
||||||
pause = (sub.AudioStatus==0x12);
|
pause = (sub.AudioStatus==0x12);
|
||||||
@ -630,27 +655,29 @@ bool CDROM_Interface_Aspi::GetAudioStatus(bool& playing, bool& pause)
|
|||||||
|
|
||||||
bool CDROM_Interface_Aspi::LoadUnloadMedia(bool unload)
|
bool CDROM_Interface_Aspi::LoadUnloadMedia(bool unload)
|
||||||
{
|
{
|
||||||
SRB_ExecSCSICmd s;DWORD dwStatus;
|
//SRB_ExecSCSICmd s;
|
||||||
|
ASPI_SRB s;
|
||||||
|
DWORD dwStatus;
|
||||||
|
|
||||||
hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
||||||
|
|
||||||
memset(&s,0,sizeof(s));
|
memset(&s,0,sizeof(s));
|
||||||
|
|
||||||
s.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
s.execscsicmd.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
||||||
s.SRB_HaId = haId;
|
s.execscsicmd.SRB_HaId = haId;
|
||||||
s.SRB_Target = target;
|
s.execscsicmd.SRB_Target = target;
|
||||||
s.SRB_Lun = lun;
|
s.execscsicmd.SRB_Lun = lun;
|
||||||
s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
s.execscsicmd.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
||||||
s.SRB_SenseLen = SENSE_LEN;
|
s.execscsicmd.SRB_SenseLen = SENSE_LEN;
|
||||||
|
|
||||||
s.SRB_BufLen = 0;
|
s.execscsicmd.SRB_BufLen = 0;
|
||||||
s.SRB_BufPointer = 0;
|
s.execscsicmd.SRB_BufPointer = 0;
|
||||||
s.SRB_CDBLen = 14;
|
s.execscsicmd.SRB_CDBLen = 6; // 14;
|
||||||
s.SRB_PostProc = (LPVOID)hEvent;
|
s.execscsicmd.SRB_PostProc = (LPVOID)hEvent;
|
||||||
|
|
||||||
s.CDBByte[0] = SCSI_LOAD_UN;
|
s.execscsicmd.CDBByte[0] = SCSI_LOAD_UN;
|
||||||
s.CDBByte[1] = (lun<<5)|1; // lun & immediate
|
s.execscsicmd.CDBByte[1] = (lun<<5)|1; // lun & immediate
|
||||||
s.CDBByte[4] = (unload ? 0x02:0x03); // unload/load media
|
s.execscsicmd.CDBByte[4] = (unload ? 0x02:0x03); // unload/load media
|
||||||
|
|
||||||
ResetEvent(hEvent);
|
ResetEvent(hEvent);
|
||||||
|
|
||||||
@ -660,7 +687,7 @@ bool CDROM_Interface_Aspi::LoadUnloadMedia(bool unload)
|
|||||||
|
|
||||||
CloseHandle(hEvent);
|
CloseHandle(hEvent);
|
||||||
|
|
||||||
if (s.SRB_Status!=SS_COMP) return false;
|
if (s.execscsicmd.SRB_Status!=SS_COMP) return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
@ -684,7 +711,9 @@ bool CDROM_Interface_Aspi::GetMediaTrayStatus(bool& mediaPresent, bool& mediaCha
|
|||||||
|
|
||||||
bool CDROM_Interface_Aspi::ReadSectors(PhysPt buffer, bool raw, unsigned long sector, unsigned long num)
|
bool CDROM_Interface_Aspi::ReadSectors(PhysPt buffer, bool raw, unsigned long sector, unsigned long num)
|
||||||
{
|
{
|
||||||
SRB_ExecSCSICmd s;DWORD dwStatus;
|
//SRB_ExecSCSICmd s;
|
||||||
|
ASPI_SRB s;
|
||||||
|
DWORD dwStatus;
|
||||||
|
|
||||||
hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
||||||
|
|
||||||
@ -693,27 +722,27 @@ bool CDROM_Interface_Aspi::ReadSectors(PhysPt buffer, bool raw, unsigned long se
|
|||||||
Bitu buflen = raw?2352*num:2048*num;
|
Bitu buflen = raw?2352*num:2048*num;
|
||||||
Bit8u* bufdata = new Bit8u[buflen];
|
Bit8u* bufdata = new Bit8u[buflen];
|
||||||
|
|
||||||
s.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
s.execscsicmd.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
||||||
s.SRB_HaId = haId;
|
s.execscsicmd.SRB_HaId = haId;
|
||||||
s.SRB_Target = target;
|
s.execscsicmd.SRB_Target = target;
|
||||||
s.SRB_Lun = lun;
|
s.execscsicmd.SRB_Lun = lun;
|
||||||
s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
s.execscsicmd.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
||||||
s.SRB_SenseLen = SENSE_LEN;
|
s.execscsicmd.SRB_SenseLen = SENSE_LEN;
|
||||||
|
|
||||||
s.SRB_BufLen = buflen;
|
s.execscsicmd.SRB_BufLen = buflen;
|
||||||
s.SRB_BufPointer = (BYTE FAR*)bufdata;
|
s.execscsicmd.SRB_BufPointer = (BYTE FAR*)bufdata;
|
||||||
s.SRB_CDBLen = 12;
|
s.execscsicmd.SRB_CDBLen = 12;
|
||||||
s.SRB_PostProc = (LPVOID)hEvent;
|
s.execscsicmd.SRB_PostProc = (LPVOID)hEvent;
|
||||||
|
|
||||||
s.CDBByte[0] = 0xBE;
|
s.execscsicmd.CDBByte[0] = 0xBE;
|
||||||
s.CDBByte[2] = (unsigned char)((sector >> 24) & 0xFF);
|
s.execscsicmd.CDBByte[2] = (unsigned char)((sector >> 24) & 0xFF);
|
||||||
s.CDBByte[3] = (unsigned char)((sector >> 16) & 0xFF);
|
s.execscsicmd.CDBByte[3] = (unsigned char)((sector >> 16) & 0xFF);
|
||||||
s.CDBByte[4] = (unsigned char)((sector >> 8) & 0xFF);
|
s.execscsicmd.CDBByte[4] = (unsigned char)((sector >> 8) & 0xFF);
|
||||||
s.CDBByte[5] = (unsigned char)((sector & 0xFF));
|
s.execscsicmd.CDBByte[5] = (unsigned char)((sector & 0xFF));
|
||||||
s.CDBByte[6] = (unsigned char)((num >> 16) & 0xFF);
|
s.execscsicmd.CDBByte[6] = (unsigned char)((num >> 16) & 0xFF);
|
||||||
s.CDBByte[7] = (unsigned char)((num >> 8) & 0xFF);
|
s.execscsicmd.CDBByte[7] = (unsigned char)((num >> 8) & 0xFF);
|
||||||
s.CDBByte[8] = (unsigned char) (num & 0xFF);
|
s.execscsicmd.CDBByte[8] = (unsigned char) (num & 0xFF);
|
||||||
s.CDBByte[9] = (raw?0xF0:0x10);
|
s.execscsicmd.CDBByte[9] = (raw?0xF0:0x10);
|
||||||
|
|
||||||
ResetEvent(hEvent);
|
ResetEvent(hEvent);
|
||||||
|
|
||||||
@ -728,7 +757,7 @@ bool CDROM_Interface_Aspi::ReadSectors(PhysPt buffer, bool raw, unsigned long se
|
|||||||
|
|
||||||
delete[] bufdata;
|
delete[] bufdata;
|
||||||
|
|
||||||
return (s.SRB_Status==SS_COMP);
|
return (s.execscsicmd.SRB_Status==SS_COMP);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
651
src/dos/cdrom_image.cpp
Normal file
651
src/dos/cdrom_image.cpp
Normal file
@ -0,0 +1,651 @@
|
|||||||
|
/*
|
||||||
|
* 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* $Id: cdrom_image.cpp,v 1.3 2004/08/23 09:35:15 harekiet Exp $ */
|
||||||
|
|
||||||
|
#include <cctype>
|
||||||
|
#include <cmath>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <limits>
|
||||||
|
#include <sstream>
|
||||||
|
#include <vector>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include "cdrom.h"
|
||||||
|
#include "drives.h"
|
||||||
|
|
||||||
|
#if !defined(WIN32)
|
||||||
|
#include <libgen.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#define MAX_LINE_LENGTH 512
|
||||||
|
#define MAX_FILENAME_LENGTH 256
|
||||||
|
|
||||||
|
CDROM_Interface_Image::BinaryFile::BinaryFile(const char *filename, bool &error)
|
||||||
|
{
|
||||||
|
file = new ifstream(filename, ios::in | ios::binary);
|
||||||
|
error = (file == NULL) || (file->fail());
|
||||||
|
}
|
||||||
|
|
||||||
|
CDROM_Interface_Image::BinaryFile::~BinaryFile()
|
||||||
|
{
|
||||||
|
delete file;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDROM_Interface_Image::BinaryFile::read(Bit8u *buffer, int seek, int count)
|
||||||
|
{
|
||||||
|
file->seekg(seek, ios::beg);
|
||||||
|
file->read((char*)buffer, count);
|
||||||
|
return !(file->fail());
|
||||||
|
}
|
||||||
|
|
||||||
|
int CDROM_Interface_Image::BinaryFile::getLength()
|
||||||
|
{
|
||||||
|
file->seekg(0, ios::end);
|
||||||
|
int length = file->tellg();
|
||||||
|
if (file->fail()) return -1;
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(C_SDL_SOUND)
|
||||||
|
CDROM_Interface_Image::AudioFile::AudioFile(const char *filename, bool &error)
|
||||||
|
{
|
||||||
|
Sound_AudioInfo desired = {AUDIO_S16, 2, 44100};
|
||||||
|
sample = Sound_NewSampleFromFile(filename, &desired, RAW_SECTOR_SIZE);
|
||||||
|
lastCount = RAW_SECTOR_SIZE;
|
||||||
|
lastSeek = 0;
|
||||||
|
error = (sample == NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
CDROM_Interface_Image::AudioFile::~AudioFile()
|
||||||
|
{
|
||||||
|
Sound_FreeSample(sample);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDROM_Interface_Image::AudioFile::read(Bit8u *buffer, int seek, int count)
|
||||||
|
{
|
||||||
|
if (lastCount != count) {
|
||||||
|
int success = Sound_SetBufferSize(sample, count);
|
||||||
|
if (!success) return false;
|
||||||
|
}
|
||||||
|
if (lastSeek != (seek - count)) {
|
||||||
|
int success = Sound_Seek(sample, (int)((double)(seek) / 176.4f));
|
||||||
|
if (!success) return false;
|
||||||
|
}
|
||||||
|
lastSeek = seek;
|
||||||
|
int bytes = Sound_Decode(sample);
|
||||||
|
if (bytes < count) {
|
||||||
|
memcpy(buffer, sample->buffer, bytes);
|
||||||
|
memset(buffer + bytes, 0, count - bytes);
|
||||||
|
} else {
|
||||||
|
memcpy(buffer, sample->buffer, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
return !(sample->flags & SOUND_SAMPLEFLAG_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
int CDROM_Interface_Image::AudioFile::getLength()
|
||||||
|
{
|
||||||
|
int time = 1;
|
||||||
|
int shift = 0;
|
||||||
|
if (!(sample->flags & SOUND_SAMPLEFLAG_CANSEEK)) return -1;
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
int success = Sound_Seek(sample, (unsigned int)(shift + time));
|
||||||
|
if (!success) {
|
||||||
|
if (time == 1) return lround((double)shift * 176.4f);
|
||||||
|
shift += time >> 1;
|
||||||
|
time = 1;
|
||||||
|
} else {
|
||||||
|
if (time > ((numeric_limits<int>::max() - shift) / 2)) return -1;
|
||||||
|
time = time << 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// initialize static members
|
||||||
|
int CDROM_Interface_Image::refCount = 0;
|
||||||
|
CDROM_Interface_Image* CDROM_Interface_Image::images[26];
|
||||||
|
CDROM_Interface_Image::imagePlayer CDROM_Interface_Image::player = {
|
||||||
|
NULL, NULL, NULL, 0, 0, 0, 0, 0, false, false };
|
||||||
|
|
||||||
|
|
||||||
|
CDROM_Interface_Image::CDROM_Interface_Image(Bit8u subUnit)
|
||||||
|
{
|
||||||
|
images[subUnit] = this;
|
||||||
|
if (refCount == 0) {
|
||||||
|
#if defined(C_SDL_SOUND)
|
||||||
|
Sound_Init();
|
||||||
|
#endif
|
||||||
|
player.mutex = SDL_CreateMutex();
|
||||||
|
if (!player.channel) {
|
||||||
|
player.channel = MIXER_AddChannel(&CDAudioCallBack, 44100, "CDAUDIO");
|
||||||
|
}
|
||||||
|
player.channel->Enable(true);
|
||||||
|
}
|
||||||
|
refCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
CDROM_Interface_Image::~CDROM_Interface_Image()
|
||||||
|
{
|
||||||
|
refCount--;
|
||||||
|
if (player.cd == this) player.cd = NULL;
|
||||||
|
ClearTracks();
|
||||||
|
if (refCount == 0) {
|
||||||
|
#if defined(C_SDL_SOUND)
|
||||||
|
Sound_Quit();
|
||||||
|
#endif
|
||||||
|
SDL_DestroyMutex(player.mutex);
|
||||||
|
player.channel->Enable(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDROM_Interface_Image::InitNewMedia()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDROM_Interface_Image::SetDevice(char* path, int forceCD)
|
||||||
|
{
|
||||||
|
if (LoadCueSheet(path)) return true;
|
||||||
|
if (LoadIsoFile(path)) return true;
|
||||||
|
|
||||||
|
// print error message on dosbox console
|
||||||
|
char buf[MAX_LINE_LENGTH];
|
||||||
|
snprintf(buf, MAX_LINE_LENGTH, "Could not load image file: %s\n", path);
|
||||||
|
Bit16u size = strlen(buf);
|
||||||
|
DOS_WriteFile(STDOUT, (Bit8u*)buf, &size);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDROM_Interface_Image::GetUPC(unsigned char& attr, char* upc)
|
||||||
|
{
|
||||||
|
attr = 0;
|
||||||
|
strcpy(upc, this->mcn.c_str());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDROM_Interface_Image::GetAudioTracks(int& stTrack, int& end, TMSF& leadOut)
|
||||||
|
{
|
||||||
|
stTrack = 1;
|
||||||
|
end = tracks.size() - 1;
|
||||||
|
FRAMES_TO_MSF(tracks[tracks.size() - 1].start + 150, &leadOut.min, &leadOut.sec, &leadOut.fr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDROM_Interface_Image::GetAudioTrackInfo(int track, TMSF& start, unsigned char& attr)
|
||||||
|
{
|
||||||
|
if (track < 1 || track > tracks.size()) return false;
|
||||||
|
FRAMES_TO_MSF(tracks[track - 1].start + 150, &start.min, &start.sec, &start.fr);
|
||||||
|
attr = tracks[track - 1].attr;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDROM_Interface_Image::GetAudioSub(unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos)
|
||||||
|
{
|
||||||
|
track = GetTrack(player.currFrame);
|
||||||
|
if (track < 1) return false;
|
||||||
|
attr = tracks[track - 1].attr;
|
||||||
|
index = 1;
|
||||||
|
FRAMES_TO_MSF(player.currFrame + 150, &absPos.min, &absPos.sec, &absPos.fr);
|
||||||
|
FRAMES_TO_MSF(player.currFrame - tracks[track - 1].start + 150, &relPos.min, &relPos.sec, &relPos.fr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDROM_Interface_Image::GetAudioStatus(bool& playing, bool& pause)
|
||||||
|
{
|
||||||
|
playing = player.isPlaying;
|
||||||
|
pause = player.isPaused;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDROM_Interface_Image::GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen)
|
||||||
|
{
|
||||||
|
mediaPresent = true;
|
||||||
|
mediaChanged = false;
|
||||||
|
trayOpen = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDROM_Interface_Image::PlayAudioSector(unsigned long start,unsigned long len)
|
||||||
|
{
|
||||||
|
SDL_mutexP(player.mutex);
|
||||||
|
player.cd = this;
|
||||||
|
player.currFrame = start;
|
||||||
|
player.targetFrame = start + len;
|
||||||
|
player.isPlaying = true;
|
||||||
|
player.isPaused = false;
|
||||||
|
SDL_mutexV(player.mutex);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDROM_Interface_Image::PauseAudio(bool resume)
|
||||||
|
{
|
||||||
|
player.isPaused = !resume;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDROM_Interface_Image::StopAudio(void)
|
||||||
|
{
|
||||||
|
player.isPlaying = false;
|
||||||
|
player.isPaused = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDROM_Interface_Image::ReadSectors(PhysPt buffer, bool raw, unsigned long sector, unsigned long num)
|
||||||
|
{
|
||||||
|
int sectorSize = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE;
|
||||||
|
Bitu buflen = num * sectorSize;
|
||||||
|
Bit8u* buf = new Bit8u[buflen];
|
||||||
|
|
||||||
|
bool success;
|
||||||
|
for(int i = 0; i < num; i++) {
|
||||||
|
success = ReadSector(&buf[i * sectorSize], raw, sector);
|
||||||
|
if (!success) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_BlockWrite(buffer, buf, buflen);
|
||||||
|
delete[] buf;
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDROM_Interface_Image::LoadUnloadMedia(bool unload)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CDROM_Interface_Image::GetTrack(int sector)
|
||||||
|
{
|
||||||
|
vector<Track>::iterator i = tracks.begin();
|
||||||
|
vector<Track>::iterator end = tracks.end() - 1;
|
||||||
|
|
||||||
|
while(i != end) {
|
||||||
|
Track &curr = *i;
|
||||||
|
Track &next = *(i + 1);
|
||||||
|
if (curr.start <= sector && sector < next.start) return curr.number;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDROM_Interface_Image::ReadSector(Bit8u *buffer, bool raw, unsigned long sector)
|
||||||
|
{
|
||||||
|
int track = GetTrack(sector) - 1;
|
||||||
|
if (track < 0) return false;
|
||||||
|
|
||||||
|
int seek = tracks[track].skip + (sector - tracks[track].start) * tracks[track].sectorSize;
|
||||||
|
int length = (raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE);
|
||||||
|
if (tracks[track].sectorSize != RAW_SECTOR_SIZE && raw) return false;
|
||||||
|
if (tracks[track].sectorSize == RAW_SECTOR_SIZE && !tracks[track].mode2 && !raw) seek += 16;
|
||||||
|
if (tracks[track].mode2 && !raw) seek += 24;
|
||||||
|
|
||||||
|
return tracks[track].file->read(buffer, seek, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDROM_Interface_Image::CDAudioCallBack(Bitu len)
|
||||||
|
{
|
||||||
|
len *= 4; // 16 bit, stereo
|
||||||
|
if (!len) return;
|
||||||
|
if (!player.isPlaying || player.isPaused) {
|
||||||
|
player.channel->AddSilence();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_mutexP(player.mutex);
|
||||||
|
while (player.bufLen < len) {
|
||||||
|
bool success;
|
||||||
|
if (player.targetFrame > player.currFrame)
|
||||||
|
success = player.cd->ReadSector(&player.buffer[player.bufLen], true, player.currFrame);
|
||||||
|
else success = false;
|
||||||
|
|
||||||
|
if (success) {
|
||||||
|
player.currFrame++;
|
||||||
|
player.bufLen += RAW_SECTOR_SIZE;
|
||||||
|
} else {
|
||||||
|
memset(&player.buffer[player.bufLen], 0, len - player.bufLen);
|
||||||
|
player.bufLen = len;
|
||||||
|
player.isPlaying = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SDL_mutexV(player.mutex);
|
||||||
|
player.channel->AddSamples_s16(len/4,(Bit16s *)player.buffer);
|
||||||
|
memmove(player.buffer, &player.buffer[len], player.bufLen - len);
|
||||||
|
player.bufLen -= len;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDROM_Interface_Image::LoadIsoFile(char* filename)
|
||||||
|
{
|
||||||
|
tracks.clear();
|
||||||
|
|
||||||
|
// data track
|
||||||
|
Track track = {0, 0, 0, 0, 0, 0, false, NULL};
|
||||||
|
bool error;
|
||||||
|
track.file = new BinaryFile(filename, error);
|
||||||
|
if (error) {
|
||||||
|
delete track.file;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
track.number = 1;
|
||||||
|
track.attr = 4;
|
||||||
|
|
||||||
|
// try to detect iso type
|
||||||
|
if (CanReadPVD(track.file, COOKED_SECTOR_SIZE, false)) {
|
||||||
|
track.sectorSize = COOKED_SECTOR_SIZE;
|
||||||
|
track.mode2 = false;
|
||||||
|
} else if (CanReadPVD(track.file, RAW_SECTOR_SIZE, false)) {
|
||||||
|
track.sectorSize = RAW_SECTOR_SIZE;
|
||||||
|
track.mode2 = false;
|
||||||
|
} else if (CanReadPVD(track.file, 2336, true)) {
|
||||||
|
track.sectorSize = 2336;
|
||||||
|
track.mode2 = true;
|
||||||
|
} else if (CanReadPVD(track.file, RAW_SECTOR_SIZE, true)) {
|
||||||
|
track.sectorSize = RAW_SECTOR_SIZE;
|
||||||
|
track.mode2 = true;
|
||||||
|
} else return false;
|
||||||
|
|
||||||
|
track.length = track.file->getLength() / track.sectorSize;
|
||||||
|
tracks.push_back(track);
|
||||||
|
|
||||||
|
// leadout track
|
||||||
|
track.number = 2;
|
||||||
|
track.attr = 0;
|
||||||
|
track.start = track.length;
|
||||||
|
track.length = 0;
|
||||||
|
track.file = NULL;
|
||||||
|
tracks.push_back(track);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDROM_Interface_Image::CanReadPVD(TrackFile *file, int sectorSize, bool mode2)
|
||||||
|
{
|
||||||
|
Bit8u pvd[COOKED_SECTOR_SIZE];
|
||||||
|
int seek = 16 * sectorSize; // first vd is located at sector 16
|
||||||
|
if (sectorSize == RAW_SECTOR_SIZE && !mode2) seek += 16;
|
||||||
|
if (mode2) seek += 24;
|
||||||
|
file->read(pvd, seek, COOKED_SECTOR_SIZE);
|
||||||
|
// pvd[0] = descriptor type, pvd[1..5] = standard identifier, pvd[6] = iso version
|
||||||
|
return (pvd[0] == 1 && !strncmp((char*)(&pvd[1]), "CD001", 5) && pvd[6] == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDROM_Interface_Image::LoadCueSheet(char *cuefile)
|
||||||
|
{
|
||||||
|
Track track = {0, 0, 0, 0, 0, 0, false, NULL};
|
||||||
|
tracks.clear();
|
||||||
|
int shift = 0;
|
||||||
|
int currPregap = 0;
|
||||||
|
int totalPregap = 0;
|
||||||
|
int prestart = 0;
|
||||||
|
bool success;
|
||||||
|
bool canAddTrack = false;
|
||||||
|
char tmp[MAX_FILENAME_LENGTH]; // dirname can change its argument
|
||||||
|
strncpy(tmp, cuefile, MAX_FILENAME_LENGTH);
|
||||||
|
#if defined(WIN32)
|
||||||
|
string pathname("");
|
||||||
|
#else
|
||||||
|
string pathname(dirname(tmp));
|
||||||
|
#endif
|
||||||
|
ifstream in;
|
||||||
|
in.open(cuefile, ios::in);
|
||||||
|
if (in.fail()) return false;
|
||||||
|
|
||||||
|
while(!in.eof()) {
|
||||||
|
// get next line
|
||||||
|
char buf[MAX_LINE_LENGTH];
|
||||||
|
in.getline(buf, MAX_LINE_LENGTH);
|
||||||
|
if (in.fail() && !in.eof()) return false; // probably a binary file
|
||||||
|
istringstream line(buf);
|
||||||
|
|
||||||
|
string command;
|
||||||
|
GetCueKeyword(command, line);
|
||||||
|
|
||||||
|
if (command == "TRACK") {
|
||||||
|
if (canAddTrack) success = AddTrack(track, shift, prestart, totalPregap, currPregap);
|
||||||
|
else success = true;
|
||||||
|
|
||||||
|
track.start = 0;
|
||||||
|
track.skip = 0;
|
||||||
|
currPregap = 0;
|
||||||
|
prestart = 0;
|
||||||
|
|
||||||
|
line >> track.number;
|
||||||
|
string type;
|
||||||
|
GetCueKeyword(type, line);
|
||||||
|
|
||||||
|
if (type == "AUDIO") {
|
||||||
|
track.sectorSize = RAW_SECTOR_SIZE;
|
||||||
|
track.attr = 0;
|
||||||
|
track.mode2 = false;
|
||||||
|
} else if (type == "MODE1/2048") {
|
||||||
|
track.sectorSize = COOKED_SECTOR_SIZE;
|
||||||
|
track.attr = 4;
|
||||||
|
track.mode2 = false;
|
||||||
|
} else if (type == "MODE1/2352") {
|
||||||
|
track.sectorSize = RAW_SECTOR_SIZE;
|
||||||
|
track.attr = 4;
|
||||||
|
track.mode2 = false;
|
||||||
|
} else if (type == "MODE2/2336") {
|
||||||
|
track.sectorSize = 2336;
|
||||||
|
track.attr = 4;
|
||||||
|
track.mode2 = true;
|
||||||
|
} else if (type == "MODE2/2352") {
|
||||||
|
track.sectorSize = RAW_SECTOR_SIZE;
|
||||||
|
track.attr = 4;
|
||||||
|
track.mode2 = true;
|
||||||
|
} else success = false;
|
||||||
|
|
||||||
|
canAddTrack = true;
|
||||||
|
}
|
||||||
|
else if (command == "INDEX") {
|
||||||
|
int index;
|
||||||
|
line >> index;
|
||||||
|
int frame;
|
||||||
|
success = GetCueFrame(frame, line);
|
||||||
|
|
||||||
|
if (index == 1) track.start = frame;
|
||||||
|
else if (index == 0) prestart = frame;
|
||||||
|
// ignore other indices
|
||||||
|
}
|
||||||
|
else if (command == "FILE") {
|
||||||
|
if (canAddTrack) success = AddTrack(track, shift, prestart, totalPregap, currPregap);
|
||||||
|
else success = true;
|
||||||
|
canAddTrack = false;
|
||||||
|
|
||||||
|
string filename;
|
||||||
|
GetCueString(filename, line);
|
||||||
|
GetRealFileName(filename, pathname);
|
||||||
|
string type;
|
||||||
|
GetCueKeyword(type, line);
|
||||||
|
|
||||||
|
track.file = NULL;
|
||||||
|
bool error = true;
|
||||||
|
if (type == "BINARY") {
|
||||||
|
track.file = new BinaryFile(filename.c_str(), error);
|
||||||
|
}
|
||||||
|
#if defined(C_SDL_SOUND)
|
||||||
|
else if (type == "WAVE" || type == "AIFF" || type == "MP3") {
|
||||||
|
track.file = new AudioFile(filename.c_str(), error);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (error) {
|
||||||
|
delete track.file;
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (command == "PREGAP") success = GetCueFrame(currPregap, line);
|
||||||
|
else if (command == "CATALOG") success = GetCueString(mcn, line);
|
||||||
|
// ignored commands
|
||||||
|
else if (command == "CDTEXTFILE" || command == "FLAGS" || command == "ISRC"
|
||||||
|
|| command == "PERFORMER" || command == "POSTGAP" || command == "REM"
|
||||||
|
|| command == "SONGWRITER" || command == "TITLE" || command == "") success = true;
|
||||||
|
// failure
|
||||||
|
else success = false;
|
||||||
|
|
||||||
|
if (!success) return false;
|
||||||
|
}
|
||||||
|
// add last track
|
||||||
|
if (!AddTrack(track, shift, prestart, totalPregap, currPregap)) return false;
|
||||||
|
|
||||||
|
// add leadout track
|
||||||
|
track.number++;
|
||||||
|
track.start = 0;
|
||||||
|
track.length = 0;
|
||||||
|
track.file = NULL;
|
||||||
|
if(!AddTrack(track, shift, 0, totalPregap, 0)) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDROM_Interface_Image::AddTrack(Track &curr, int &shift, int prestart, int &totalPregap, int currPregap)
|
||||||
|
{
|
||||||
|
// frames between index 0(prestart) and 1(curr.start) must be skipped
|
||||||
|
int skip;
|
||||||
|
if (prestart > 0) {
|
||||||
|
if (prestart > curr.start) return false;
|
||||||
|
skip = curr.start - prestart;
|
||||||
|
} else skip = 0;
|
||||||
|
|
||||||
|
// first track (track number must be 1)
|
||||||
|
if (tracks.empty()) {
|
||||||
|
if (curr.number != 1) return false;
|
||||||
|
curr.skip = skip * curr.sectorSize;
|
||||||
|
curr.start += currPregap;
|
||||||
|
totalPregap = currPregap;
|
||||||
|
tracks.push_back(curr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Track &prev = *(tracks.end() - 1);
|
||||||
|
|
||||||
|
// current track consumes data from the same file as the previous
|
||||||
|
if (prev.file == curr.file) {
|
||||||
|
curr.start += shift;
|
||||||
|
prev.length = curr.start + totalPregap - prev.start - skip;
|
||||||
|
curr.skip += prev.skip + prev.length * prev.sectorSize + skip * curr.sectorSize;
|
||||||
|
totalPregap += currPregap;
|
||||||
|
curr.start += totalPregap;
|
||||||
|
// current track uses a different file as the previous track
|
||||||
|
} else {
|
||||||
|
int tmp = prev.file->getLength() - prev.skip;
|
||||||
|
prev.length = tmp / prev.sectorSize;
|
||||||
|
if (tmp % prev.sectorSize != 0) prev.length++; // padding
|
||||||
|
|
||||||
|
curr.start += prev.start + prev.length + currPregap;
|
||||||
|
curr.skip = skip * curr.sectorSize;
|
||||||
|
shift += prev.start + prev.length;
|
||||||
|
totalPregap = currPregap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// error checks
|
||||||
|
if (curr.number <= 1) return false;
|
||||||
|
if (prev.number + 1 != curr.number) return false;
|
||||||
|
if (curr.start < prev.start + prev.length) return false;
|
||||||
|
if (curr.length < 0) return false;
|
||||||
|
|
||||||
|
tracks.push_back(curr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDROM_Interface_Image::GetRealFileName(string &filename, string &pathname)
|
||||||
|
{
|
||||||
|
// check if file exists
|
||||||
|
struct stat test;
|
||||||
|
if (stat(filename.c_str(), &test) == 0) return true;
|
||||||
|
|
||||||
|
// check if file with path relative to cue file exists
|
||||||
|
#if not defined(WIN32)
|
||||||
|
string tmpstr(pathname + "/" + filename);
|
||||||
|
if (stat(tmpstr.c_str(), &test) == 0) {
|
||||||
|
filename = tmpstr;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// finally check if file is in a dosbox local drive
|
||||||
|
char fullname[CROSS_LEN];
|
||||||
|
char tmp[CROSS_LEN];
|
||||||
|
strncpy(tmp, filename.c_str(), CROSS_LEN);
|
||||||
|
Bit8u drive;
|
||||||
|
if (!DOS_MakeName(tmp, fullname, &drive)) return false;
|
||||||
|
|
||||||
|
localDrive *ldp = (localDrive*)Drives[drive];
|
||||||
|
ldp->GetSystemFilename(tmp, fullname);
|
||||||
|
if (stat(tmp, &test) == 0) {
|
||||||
|
filename = tmp;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDROM_Interface_Image::GetCueKeyword(string &keyword, istream &in)
|
||||||
|
{
|
||||||
|
in >> keyword;
|
||||||
|
for(int i = 0; i < keyword.size(); i++) keyword[i] = toupper(keyword[i]);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDROM_Interface_Image::GetCueFrame(int &frames, istream &in)
|
||||||
|
{
|
||||||
|
string msf;
|
||||||
|
in >> msf;
|
||||||
|
int min, sec, fr;
|
||||||
|
bool success = sscanf(msf.c_str(), "%d:%d:%d", &min, &sec, &fr) == 3;
|
||||||
|
frames = MSF_TO_FRAMES(min, sec, fr);
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDROM_Interface_Image::GetCueString(string &str, istream &in)
|
||||||
|
{
|
||||||
|
int pos = in.tellg();
|
||||||
|
in >> str;
|
||||||
|
if (str[0] == '\"') {
|
||||||
|
if (str[str.size() - 1] == '\"') {
|
||||||
|
str.assign(str, 1, str.size() - 2);
|
||||||
|
} else {
|
||||||
|
in.seekg(pos, ios::beg);
|
||||||
|
char buffer[MAX_FILENAME_LENGTH];
|
||||||
|
in.getline(buffer, MAX_FILENAME_LENGTH, '\"'); // skip
|
||||||
|
in.getline(buffer, MAX_FILENAME_LENGTH, '\"');
|
||||||
|
str = buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDROM_Interface_Image::ClearTracks()
|
||||||
|
{
|
||||||
|
vector<Track>::iterator i = tracks.begin();
|
||||||
|
vector<Track>::iterator end = tracks.end();
|
||||||
|
|
||||||
|
TrackFile* last = NULL;
|
||||||
|
while(i != end) {
|
||||||
|
Track &curr = *i;
|
||||||
|
if (curr.file != last) {
|
||||||
|
delete curr.file;
|
||||||
|
last = curr.file;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
tracks.clear();
|
||||||
|
}
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
|
@ -9,14 +9,14 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: cdrom_ioctl_win32.cpp,v 1.10 2004/01/10 14:03:34 qbix79 Exp $ */
|
/* $Id: cdrom_ioctl_win32.cpp,v 1.11 2004/08/04 09:12:53 qbix79 Exp $ */
|
||||||
|
|
||||||
#if defined (WIN32)
|
#if defined (WIN32)
|
||||||
|
|
||||||
|
@ -9,14 +9,14 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: dev_con.h,v 1.16 2004/01/10 14:03:34 qbix79 Exp $ */
|
/* $Id: dev_con.h,v 1.18 2004/08/26 19:41:20 qbix79 Exp $ */
|
||||||
|
|
||||||
#include "dos_inc.h"
|
#include "dos_inc.h"
|
||||||
#include "../ints/int10.h"
|
#include "../ints/int10.h"
|
||||||
@ -55,11 +55,8 @@ bool device_CON::Read(Bit8u * data,Bit16u * size) {
|
|||||||
Bit16u count=0;
|
Bit16u count=0;
|
||||||
if ((cache) && (*size)) {
|
if ((cache) && (*size)) {
|
||||||
data[count++]=cache;
|
data[count++]=cache;
|
||||||
if(dos.echo) {
|
if(dos.echo) INT10_TeletypeOutput(cache,7);
|
||||||
INT10_TeletypeOutput(cache,7);
|
|
||||||
}
|
|
||||||
cache=0;
|
cache=0;
|
||||||
|
|
||||||
}
|
}
|
||||||
while (*size>count) {
|
while (*size>count) {
|
||||||
reg_ah=0;
|
reg_ah=0;
|
||||||
@ -85,7 +82,6 @@ bool device_CON::Read(Bit8u * data,Bit16u * size) {
|
|||||||
} else {
|
} else {
|
||||||
continue; //no data read yet so restart whileloop.
|
continue; //no data read yet so restart whileloop.
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
data[count++]=reg_al;
|
data[count++]=reg_al;
|
||||||
@ -95,7 +91,6 @@ bool device_CON::Read(Bit8u * data,Bit16u * size) {
|
|||||||
if (*size>count) data[count++]=reg_ah;
|
if (*size>count) data[count++]=reg_ah;
|
||||||
else cache=reg_ah;
|
else cache=reg_ah;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
if(dos.echo) { //what to do if *size==1 and character is BS ?????
|
if(dos.echo) { //what to do if *size==1 and character is BS ?????
|
||||||
INT10_TeletypeOutput(reg_al,7);
|
INT10_TeletypeOutput(reg_al,7);
|
||||||
@ -121,14 +116,13 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) {
|
|||||||
ansi.esc=true;
|
ansi.esc=true;
|
||||||
count++;
|
count++;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// pass attribute only if ansi is enabled
|
/* pass attribute only if ansi is enabled */
|
||||||
INT10_TeletypeOutputAttr(data[count],ansi.attr,ansi.enabled);
|
INT10_TeletypeOutputAttr(data[count],ansi.attr,ansi.enabled);
|
||||||
count++;
|
count++;
|
||||||
continue;
|
continue;
|
||||||
};
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
if(!ansi.sci){
|
if(!ansi.sci){
|
||||||
|
|
||||||
@ -147,7 +141,6 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) {
|
|||||||
}
|
}
|
||||||
count++;
|
count++;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
}
|
}
|
||||||
/*ansi.esc and ansi.sci are true */
|
/*ansi.esc and ansi.sci are true */
|
||||||
switch(data[count]){
|
switch(data[count]){
|
||||||
@ -171,20 +164,20 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) {
|
|||||||
ansi.enabled=true;
|
ansi.enabled=true;
|
||||||
switch(ansi.data[i]){
|
switch(ansi.data[i]){
|
||||||
case 0: /* normal */
|
case 0: /* normal */
|
||||||
ansi.attr=0x7;
|
ansi.attr=0x07;//Real ansi does this as well. (should do current defaults)
|
||||||
ansi.enabled=false;
|
ansi.enabled=false;
|
||||||
break;
|
break;
|
||||||
case 1: /* bold mode on*/
|
case 1: /* bold mode on*/
|
||||||
ansi.attr|=0x8;
|
ansi.attr|=0x08;
|
||||||
break;
|
break;
|
||||||
case 4: /* underline */
|
case 4: /* underline */
|
||||||
LOG(LOG_IOCTL,LOG_NORMAL)("ANSI:no support for underline yet");
|
LOG(LOG_IOCTL,LOG_NORMAL)("ANSI:no support for underline yet");
|
||||||
break;
|
break;
|
||||||
case 5: /* blinking */
|
case 5: /* blinking */
|
||||||
LOG(LOG_IOCTL,LOG_NORMAL)("ANSI:no support for blinking yet");
|
ansi.attr|=0x80;
|
||||||
break;
|
break;
|
||||||
case 7: /* reverse */
|
case 7: /* reverse */
|
||||||
LOG(LOG_IOCTL,LOG_NORMAL)("ANSI:no support for reverse yet");
|
ansi.attr=0x70;//Just like real ansi. (should do use current colors reversed)
|
||||||
break;
|
break;
|
||||||
case 30: /* fg color black */
|
case 30: /* fg color black */
|
||||||
ansi.attr&=0xf8;
|
ansi.attr&=0xf8;
|
||||||
@ -252,7 +245,6 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) {
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ClearAnsi();
|
ClearAnsi();
|
||||||
@ -264,15 +256,14 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) {
|
|||||||
INT10_SetCursorPos(--(ansi.data[0]),--(ansi.data[1]),0); /*ansi=1 based, int10 is 0 based */
|
INT10_SetCursorPos(--(ansi.data[0]),--(ansi.data[1]),0); /*ansi=1 based, int10 is 0 based */
|
||||||
ClearAnsi();
|
ClearAnsi();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* cursor up down and forward and backward only change the row or the col not both */
|
/* cursor up down and forward and backward only change the row or the col not both */
|
||||||
case 'A': /* cursor up*/
|
case 'A': /* cursor up*/
|
||||||
col=CURSOR_POS_COL(0) ;
|
col=CURSOR_POS_COL(0) ;
|
||||||
row=CURSOR_POS_ROW(0) ;
|
row=CURSOR_POS_ROW(0) ;
|
||||||
tempdata = (ansi.data[0]? ansi.data[0] : 1);
|
tempdata = (ansi.data[0]? ansi.data[0] : 1);
|
||||||
if(tempdata > row)
|
if(tempdata > row) { row=0; }
|
||||||
{ row=0; }
|
else { row-=tempdata;}
|
||||||
else
|
|
||||||
{ row-=tempdata;}
|
|
||||||
INT10_SetCursorPos(row,col,0);
|
INT10_SetCursorPos(row,col,0);
|
||||||
ClearAnsi();
|
ClearAnsi();
|
||||||
break;
|
break;
|
||||||
@ -282,8 +273,7 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) {
|
|||||||
tempdata = (ansi.data[0]? ansi.data[0] : 1);
|
tempdata = (ansi.data[0]? ansi.data[0] : 1);
|
||||||
if(tempdata + static_cast<Bitu>(row) >= ansi.nrows)
|
if(tempdata + static_cast<Bitu>(row) >= ansi.nrows)
|
||||||
{ row = ansi.nrows - 1;}
|
{ row = ansi.nrows - 1;}
|
||||||
else
|
else { row += tempdata; }
|
||||||
{ row += tempdata; }
|
|
||||||
INT10_SetCursorPos(row,col,0);
|
INT10_SetCursorPos(row,col,0);
|
||||||
ClearAnsi();
|
ClearAnsi();
|
||||||
break;
|
break;
|
||||||
@ -293,8 +283,7 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) {
|
|||||||
tempdata=(ansi.data[0]? ansi.data[0] : 1);
|
tempdata=(ansi.data[0]? ansi.data[0] : 1);
|
||||||
if(tempdata + static_cast<Bitu>(col) >= ansi.ncols)
|
if(tempdata + static_cast<Bitu>(col) >= ansi.ncols)
|
||||||
{ col = ansi.ncols - 1;}
|
{ col = ansi.ncols - 1;}
|
||||||
else
|
else { col += tempdata;}
|
||||||
{ col += tempdata;}
|
|
||||||
INT10_SetCursorPos(row,col,0);
|
INT10_SetCursorPos(row,col,0);
|
||||||
ClearAnsi();
|
ClearAnsi();
|
||||||
break;
|
break;
|
||||||
@ -302,10 +291,8 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) {
|
|||||||
col=CURSOR_POS_COL(0);
|
col=CURSOR_POS_COL(0);
|
||||||
row=CURSOR_POS_ROW(0);
|
row=CURSOR_POS_ROW(0);
|
||||||
tempdata=(ansi.data[0]? ansi.data[0] : 1);
|
tempdata=(ansi.data[0]? ansi.data[0] : 1);
|
||||||
if(tempdata > col)
|
if(tempdata > col) {col = 0;}
|
||||||
{col = 0;}
|
else { col -= tempdata;}
|
||||||
else
|
|
||||||
{ col -= tempdata;}
|
|
||||||
INT10_SetCursorPos(row,col,0);
|
INT10_SetCursorPos(row,col,0);
|
||||||
ClearAnsi();
|
ClearAnsi();
|
||||||
break;
|
break;
|
||||||
@ -372,12 +359,8 @@ Bit16u device_CON::GetInformation(void) {
|
|||||||
device_CON::device_CON() {
|
device_CON::device_CON() {
|
||||||
name="CON";
|
name="CON";
|
||||||
cache=0;
|
cache=0;
|
||||||
ansi.esc=false;
|
|
||||||
ansi.sci=false;
|
|
||||||
ansi.enabled=false;
|
ansi.enabled=false;
|
||||||
ansi.attr=0x7;
|
ansi.attr=0x7;
|
||||||
ansi.numberofarg=0;
|
|
||||||
for(Bit8u i=0; i<NUMBER_ANSI_DATA;i++) ansi.data[i]=0;
|
|
||||||
ansi.ncols=real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS); //should be updated once set/reset mode is implemented
|
ansi.ncols=real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS); //should be updated once set/reset mode is implemented
|
||||||
ansi.nrows=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS) + 1;
|
ansi.nrows=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS) + 1;
|
||||||
ansi.saverow=0;
|
ansi.saverow=0;
|
||||||
|
153
src/dos/dos.cpp
153
src/dos/dos.cpp
@ -9,14 +9,14 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: dos.cpp,v 1.65 2004/02/02 11:38:44 qbix79 Exp $ */
|
/* $Id: dos.cpp,v 1.75 2004/09/21 20:04:55 qbix79 Exp $ */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -45,9 +45,10 @@ void DOS_SetError(Bit16u code) {
|
|||||||
#define DOSNAMEBUF 256
|
#define DOSNAMEBUF 256
|
||||||
static Bitu DOS_21Handler(void) {
|
static Bitu DOS_21Handler(void) {
|
||||||
if (((reg_ah != 0x50) && (reg_ah != 0x51) && (reg_ah != 0x62) && (reg_ah != 0x64)) && (reg_ah<0x6c)) {
|
if (((reg_ah != 0x50) && (reg_ah != 0x51) && (reg_ah != 0x62) && (reg_ah != 0x64)) && (reg_ah<0x6c)) {
|
||||||
DOS_PSP psp(dos.psp);
|
DOS_PSP psp(dos.psp());
|
||||||
psp.SetStack(RealMake(SegValue(ss),reg_sp-20));
|
psp.SetStack(RealMake(SegValue(ss),reg_sp-18));
|
||||||
}
|
}
|
||||||
|
|
||||||
char name1[DOSNAMEBUF+1];
|
char name1[DOSNAMEBUF+1];
|
||||||
char name2[DOSNAMEBUF+1];
|
char name2[DOSNAMEBUF+1];
|
||||||
switch (reg_ah) {
|
switch (reg_ah) {
|
||||||
@ -58,7 +59,6 @@ static Bitu DOS_21Handler(void) {
|
|||||||
DOS_ReadFile(STDIN,&c,&n);
|
DOS_ReadFile(STDIN,&c,&n);
|
||||||
reg_al=c;
|
reg_al=c;
|
||||||
dos.echo=false;
|
dos.echo=false;
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x02: /* Write character to STDOUT */
|
case 0x02: /* Write character to STDOUT */
|
||||||
@ -254,7 +254,8 @@ static Bitu DOS_21Handler(void) {
|
|||||||
LOG(LOG_FCB,LOG_NORMAL)("DOS:0x28 FCB-Random(block) write used, result:al=%d",reg_al);
|
LOG(LOG_FCB,LOG_NORMAL)("DOS:0x28 FCB-Random(block) write used, result:al=%d",reg_al);
|
||||||
break;
|
break;
|
||||||
case 0x29: /* Parse filename into FCB */
|
case 0x29: /* Parse filename into FCB */
|
||||||
{ Bit8u difference;
|
{
|
||||||
|
Bit8u difference;
|
||||||
char string[1024];
|
char string[1024];
|
||||||
MEM_StrCopy(SegPhys(ds)+reg_si,string,1024);
|
MEM_StrCopy(SegPhys(ds)+reg_si,string,1024);
|
||||||
reg_al=FCB_Parsename(SegValue(es),reg_di,reg_al ,string, &difference);
|
reg_al=FCB_Parsename(SegValue(es),reg_di,reg_al ,string, &difference);
|
||||||
@ -266,17 +267,13 @@ static Bitu DOS_21Handler(void) {
|
|||||||
reg_al=DOS_GetDefaultDrive();
|
reg_al=DOS_GetDefaultDrive();
|
||||||
break;
|
break;
|
||||||
case 0x1a: /* Set Disk Transfer Area Address */
|
case 0x1a: /* Set Disk Transfer Area Address */
|
||||||
{
|
dos.dta(RealMakeSeg(ds,reg_dx));
|
||||||
dos.dta=RealMakeSeg(ds,reg_dx);
|
|
||||||
DOS_PSP psp(dos.psp);
|
|
||||||
psp.SetDTA(dos.dta);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 0x25: /* Set Interrupt Vector */
|
case 0x25: /* Set Interrupt Vector */
|
||||||
RealSetVec(reg_al,RealMakeSeg(ds,reg_dx));
|
RealSetVec(reg_al,RealMakeSeg(ds,reg_dx));
|
||||||
break;
|
break;
|
||||||
case 0x26: /* Create new PSP */
|
case 0x26: /* Create new PSP */
|
||||||
DOS_NewPSP(reg_dx,DOS_PSP(dos.psp).GetSize());
|
DOS_NewPSP(reg_dx,DOS_PSP(dos.psp()).GetSize());
|
||||||
break;
|
break;
|
||||||
case 0x2a: /* Get System Date */
|
case 0x2a: /* Get System Date */
|
||||||
{
|
{
|
||||||
@ -319,29 +316,43 @@ static Bitu DOS_21Handler(void) {
|
|||||||
dos.verify=(reg_al==1);
|
dos.verify=(reg_al==1);
|
||||||
break;
|
break;
|
||||||
case 0x2f: /* Get Disk Transfer Area */
|
case 0x2f: /* Get Disk Transfer Area */
|
||||||
SegSet16(es,RealSeg(dos.dta));
|
SegSet16(es,RealSeg(dos.dta()));
|
||||||
reg_bx=RealOff(dos.dta);
|
reg_bx=RealOff(dos.dta());
|
||||||
break;
|
break;
|
||||||
case 0x30: /* Get DOS Version */
|
case 0x30: /* Get DOS Version */
|
||||||
if (reg_al==0) reg_bh=0xFF; /* Fake Microsoft DOS */
|
if (reg_al==0) reg_bh=0xFF; /* Fake Microsoft DOS */
|
||||||
if (reg_al==1) reg_bh=0x10; /* DOS is in HMA */
|
if (reg_al==1) reg_bh=0x10; /* DOS is in HMA */
|
||||||
reg_al=dos.version.major;
|
reg_al=dos.version.major;
|
||||||
reg_ah=dos.version.minor;
|
reg_ah=dos.version.minor;
|
||||||
|
/* Serialnumber */
|
||||||
|
reg_bl=0x00;
|
||||||
|
reg_cx=0x0000;
|
||||||
break;
|
break;
|
||||||
case 0x31: /* Terminate and stay resident */
|
case 0x31: /* Terminate and stay resident */
|
||||||
//TODO First get normal files executing
|
//TODO First get normal files executing
|
||||||
// Important: This service does not set the carry flag!
|
// Important: This service does not set the carry flag!
|
||||||
DOS_ResizeMemory(dos.psp,®_dx);
|
DOS_ResizeMemory(dos.psp(),®_dx);
|
||||||
DOS_Terminate(true);
|
DOS_Terminate(true);
|
||||||
dos.return_code=reg_al;
|
dos.return_code=reg_al; //Officially a field in the SDA
|
||||||
dos.return_mode=RETURN_TSR;
|
dos.return_mode=RETURN_TSR;
|
||||||
break;
|
break;
|
||||||
|
case 0x32: /* Get drive parameter block for specific drive */
|
||||||
|
{ /* Officially a dpb should be returned as well. The disk detection part is implemented */
|
||||||
|
Bitu drive=reg_dl;if(!drive) drive=dos.current_drive;else drive--;
|
||||||
|
if(Drives[drive]) {
|
||||||
|
reg_al=0x00;
|
||||||
|
LOG(LOG_DOSMISC,LOG_ERROR)("Get drive parameter block.");
|
||||||
|
} else {
|
||||||
|
reg_al=0xff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 0x33: /* Extended Break Checking */
|
case 0x33: /* Extended Break Checking */
|
||||||
switch (reg_al) {
|
switch (reg_al) {
|
||||||
case 0:reg_dl=dos.breakcheck;break; /* Get the breakcheck flag */
|
case 0:reg_dl=dos.breakcheck;break; /* Get the breakcheck flag */
|
||||||
case 1:dos.breakcheck=(reg_dl>0);break; /* Set the breakcheck flag */
|
case 1:dos.breakcheck=(reg_dl>0);break; /* Set the breakcheck flag */
|
||||||
case 2:{bool old=dos.breakcheck;dos.breakcheck=(reg_dl>0);reg_dl=old;}break;
|
case 2:{bool old=dos.breakcheck;dos.breakcheck=(reg_dl>0);reg_dl=old;}break;
|
||||||
case 5:reg_dl=3;break; /* Always boot from c: :) */
|
case 5:reg_dl=3;break;//TODO should be z /* Always boot from c: :) */
|
||||||
case 6: /* Get true version number */
|
case 6: /* Get true version number */
|
||||||
reg_bl=dos.version.major;
|
reg_bl=dos.version.major;
|
||||||
reg_bh=dos.version.minor;
|
reg_bh=dos.version.minor;
|
||||||
@ -353,8 +364,8 @@ static Bitu DOS_21Handler(void) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x34: /* Get INDos Flag */
|
case 0x34: /* Get INDos Flag */
|
||||||
SegSet16(es,RealSeg(dos.tables.indosflag));
|
SegSet16(es,DOS_SDA_SEG);
|
||||||
reg_bx=RealOff(dos.tables.indosflag);
|
reg_bx=DOS_SDA_OFS + 0x01;
|
||||||
break;
|
break;
|
||||||
case 0x35: /* Get interrupt vector */
|
case 0x35: /* Get interrupt vector */
|
||||||
reg_bx=real_readw(0,((Bit16u)reg_al)*4);
|
reg_bx=real_readw(0,((Bit16u)reg_al)*4);
|
||||||
@ -364,7 +375,7 @@ static Bitu DOS_21Handler(void) {
|
|||||||
{
|
{
|
||||||
Bit16u bytes,clusters,free;
|
Bit16u bytes,clusters,free;
|
||||||
Bit8u sectors;
|
Bit8u sectors;
|
||||||
if (DOS_GetFreeDiskSpace(reg_dl,&bytes,§ors,&clusters,&free)) {
|
if(DOS_GetFreeDiskSpace(reg_dl,&bytes,§ors,&clusters,&free)) {
|
||||||
reg_ax=sectors;
|
reg_ax=sectors;
|
||||||
reg_bx=free;
|
reg_bx=free;
|
||||||
reg_cx=bytes;
|
reg_cx=bytes;
|
||||||
@ -634,7 +645,7 @@ static Bitu DOS_21Handler(void) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x4d: /* Get Return code */
|
case 0x4d: /* Get Return code */
|
||||||
reg_al=dos.return_code;
|
reg_al=dos.return_code;/* Officially read from SDA and clear when read */
|
||||||
reg_ah=dos.return_mode;
|
reg_ah=dos.return_mode;
|
||||||
break;
|
break;
|
||||||
case 0x4e: /* FINDFIRST Find first matching file */
|
case 0x4e: /* FINDFIRST Find first matching file */
|
||||||
@ -650,17 +661,18 @@ static Bitu DOS_21Handler(void) {
|
|||||||
case 0x4f: /* FINDNEXT Find next matching file */
|
case 0x4f: /* FINDNEXT Find next matching file */
|
||||||
if (DOS_FindNext()) {
|
if (DOS_FindNext()) {
|
||||||
CALLBACK_SCF(false);
|
CALLBACK_SCF(false);
|
||||||
reg_ax=0xffff; /* Undocumented */
|
/* reg_ax=0xffff;*/ /* Undocumented */
|
||||||
|
reg_ax=0; /* Undocumented:Qbix Willy beamish */
|
||||||
} else {
|
} else {
|
||||||
reg_ax=dos.errorcode;
|
reg_ax=dos.errorcode;
|
||||||
CALLBACK_SCF(true);
|
CALLBACK_SCF(true);
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
case 0x50: /* Set current PSP */
|
case 0x50: /* Set current PSP */
|
||||||
dos.psp=reg_bx;
|
dos.psp(reg_bx);
|
||||||
break;
|
break;
|
||||||
case 0x51: /* Get current PSP */
|
case 0x51: /* Get current PSP */
|
||||||
reg_bx=dos.psp;
|
reg_bx=dos.psp();
|
||||||
break;
|
break;
|
||||||
case 0x52: { /* Get list of lists */
|
case 0x52: { /* Get list of lists */
|
||||||
RealPt addr=dos_infoblock.GetPointer();
|
RealPt addr=dos_infoblock.GetPointer();
|
||||||
@ -678,7 +690,7 @@ static Bitu DOS_21Handler(void) {
|
|||||||
break;
|
break;
|
||||||
case 0x55: /* Create Child PSP*/
|
case 0x55: /* Create Child PSP*/
|
||||||
DOS_ChildPSP(reg_dx,reg_si);
|
DOS_ChildPSP(reg_dx,reg_si);
|
||||||
dos.psp = reg_dx;
|
dos.psp(reg_dx);
|
||||||
break;
|
break;
|
||||||
case 0x56: /* RENAME Rename file */
|
case 0x56: /* RENAME Rename file */
|
||||||
MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF);
|
MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF);
|
||||||
@ -736,6 +748,7 @@ static Bitu DOS_21Handler(void) {
|
|||||||
MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF);
|
MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF);
|
||||||
if (DOS_CreateTempFile(name1,&handle)) {
|
if (DOS_CreateTempFile(name1,&handle)) {
|
||||||
reg_ax=handle;
|
reg_ax=handle;
|
||||||
|
MEM_BlockWrite(SegPhys(ds)+reg_dx,name1,strlen(name1)+1);
|
||||||
CALLBACK_SCF(false);
|
CALLBACK_SCF(false);
|
||||||
} else {
|
} else {
|
||||||
reg_ax=dos.errorcode;
|
reg_ax=dos.errorcode;
|
||||||
@ -763,6 +776,19 @@ static Bitu DOS_21Handler(void) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 0x5d: /* Network Functions */
|
||||||
|
if(reg_al == 0x06) {
|
||||||
|
SegSet16(ds,DOS_SDA_SEG);
|
||||||
|
reg_si = DOS_SDA_OFS;
|
||||||
|
reg_cx = 0x80; // swap if in dos
|
||||||
|
reg_dx = 0x1a; // swap always
|
||||||
|
LOG(LOG_DOSMISC,LOG_ERROR)("Get SDA, Let's hope for the best!");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x5f: /* Network redirection */
|
||||||
|
reg_ax=0x0001; //Failing it
|
||||||
|
CALLBACK_SCF(true);
|
||||||
|
break;
|
||||||
case 0x60: /* Canonicalize filename or path */
|
case 0x60: /* Canonicalize filename or path */
|
||||||
MEM_StrCopy(SegPhys(ds)+reg_si,name1,DOSNAMEBUF);
|
MEM_StrCopy(SegPhys(ds)+reg_si,name1,DOSNAMEBUF);
|
||||||
if (DOS_Canonicalize(name1,name2)) {
|
if (DOS_Canonicalize(name1,name2)) {
|
||||||
@ -774,7 +800,15 @@ static Bitu DOS_21Handler(void) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x62: /* Get Current PSP Address */
|
case 0x62: /* Get Current PSP Address */
|
||||||
reg_bx=dos.psp;
|
reg_bx=dos.psp();
|
||||||
|
break;
|
||||||
|
case 0x63: /* DOUBLE BYTE CHARACTER SET */
|
||||||
|
if(reg_al == 0) {
|
||||||
|
SegSet16(ds,RealSeg(dos.tables.dcbs));
|
||||||
|
reg_si=RealOff(dos.tables.dcbs);
|
||||||
|
reg_al = 0;
|
||||||
|
CALLBACK_SCF(false); //undocumented
|
||||||
|
} else reg_al = 0xff; //Doesn't officially touch carry flag
|
||||||
break;
|
break;
|
||||||
case 0x64: /* Set device driver lookahead flag */
|
case 0x64: /* Set device driver lookahead flag */
|
||||||
E_Exit("Unhandled Dos 21 call %02X",reg_ah);
|
E_Exit("Unhandled Dos 21 call %02X",reg_ah);
|
||||||
@ -787,10 +821,23 @@ static Bitu DOS_21Handler(void) {
|
|||||||
switch (reg_al) {
|
switch (reg_al) {
|
||||||
case 1:
|
case 1:
|
||||||
mem_writeb(data,reg_al);
|
mem_writeb(data,reg_al);
|
||||||
mem_writew(data+1,4);
|
mem_writew(data+0x01,0x1c);
|
||||||
mem_writew(data+3,1);
|
mem_writew(data+0x03,1);
|
||||||
mem_writew(data+5,37);
|
mem_writew(data+0x05,0x01b5);
|
||||||
reg_cx=4;
|
mem_writew(data+0x07,0x0000); // date format
|
||||||
|
mem_writeb(data+0x08,0x24); // currency symbol
|
||||||
|
mem_writew(data+0x0a,0x0000);
|
||||||
|
mem_writew(data+0x0c,0x0000);
|
||||||
|
mem_writew(data+0x0e,0x002c); // thousands separator
|
||||||
|
mem_writew(data+0x10,0x002e); // decimal separator
|
||||||
|
mem_writew(data+0x12,0x002d); // date separator
|
||||||
|
mem_writew(data+0x14,0x003a); // time separator
|
||||||
|
mem_writeb(data+0x16,0x00); // currency format
|
||||||
|
mem_writeb(data+0x17,0x02); // digits after decimal in currency
|
||||||
|
mem_writeb(data+0x18,0x00); // time format
|
||||||
|
mem_writed(data+0x19,CALLBACK_RealPointer(call_casemap));
|
||||||
|
mem_writew(data+0x1d,0x002c); // list separator
|
||||||
|
reg_cx=0x1f;
|
||||||
CALLBACK_SCF(false);
|
CALLBACK_SCF(false);
|
||||||
break;
|
break;
|
||||||
case 2: // Get pointer to uppercase table
|
case 2: // Get pointer to uppercase table
|
||||||
@ -799,9 +846,9 @@ static Bitu DOS_21Handler(void) {
|
|||||||
case 5: // Get pointer to filename terminator table
|
case 5: // Get pointer to filename terminator table
|
||||||
case 6: // Get pointer to collating sequence table
|
case 6: // Get pointer to collating sequence table
|
||||||
case 7: // Get pointer to double byte char set table
|
case 7: // Get pointer to double byte char set table
|
||||||
mem_writew(data ,0x0000); // We dont have this table...
|
mem_writeb(data,reg_al);
|
||||||
mem_writew(data+2,0x0000); // End of table
|
mem_writed(data+1,dos.tables.dcbs); //used to be 0
|
||||||
reg_cx=4;
|
reg_cx=5;
|
||||||
CALLBACK_SCF(false);
|
CALLBACK_SCF(false);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -821,7 +868,7 @@ static Bitu DOS_21Handler(void) {
|
|||||||
case 0x67: /* Set handle count */
|
case 0x67: /* Set handle count */
|
||||||
/* Weird call to increase amount of file handles needs to allocate memory if >20 */
|
/* Weird call to increase amount of file handles needs to allocate memory if >20 */
|
||||||
{
|
{
|
||||||
DOS_PSP psp(dos.psp);
|
DOS_PSP psp(dos.psp());
|
||||||
psp.SetNumFiles(reg_bx);
|
psp.SetNumFiles(reg_bx);
|
||||||
CALLBACK_SCF(false);
|
CALLBACK_SCF(false);
|
||||||
break;
|
break;
|
||||||
@ -854,8 +901,8 @@ static Bitu DOS_21Handler(void) {
|
|||||||
CALLBACK_SCF(true);
|
CALLBACK_SCF(true);
|
||||||
LOG(LOG_DOSMISC,LOG_NORMAL)("DOS:Windows long file name support call %2X",reg_al);
|
LOG(LOG_DOSMISC,LOG_NORMAL)("DOS:Windows long file name support call %2X",reg_al);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x68: /* FFLUSH Commit file */
|
case 0x68: /* FFLUSH Commit file */
|
||||||
case 0x63: /* Weirdo double byte stuff (fails but say it succeeded) available only in MSDOS 2.25 */
|
|
||||||
CALLBACK_SCF(false); //mirek
|
CALLBACK_SCF(false); //mirek
|
||||||
case 0xE0:
|
case 0xE0:
|
||||||
case 0x18: /* NULL Function for CP/M compatibility or Extended rename FCB */
|
case 0x18: /* NULL Function for CP/M compatibility or Extended rename FCB */
|
||||||
@ -865,13 +912,10 @@ static Bitu DOS_21Handler(void) {
|
|||||||
case 0x6b: /* NULL Function */
|
case 0x6b: /* NULL Function */
|
||||||
case 0x61: /* UNUSED */
|
case 0x61: /* UNUSED */
|
||||||
case 0xEF: /* Used in Ancient Art Of War CGA */
|
case 0xEF: /* Used in Ancient Art Of War CGA */
|
||||||
case 0x5d: /* Network Functions ||HMMM seems to critical error info and return 1!! Maybe implement it.??*/
|
|
||||||
/* al=06 clears cf and leaves al=6 and returns crit error flag location*/
|
|
||||||
case 0x1f: /* Get drive parameter block for default drive */
|
case 0x1f: /* Get drive parameter block for default drive */
|
||||||
case 0x32: /* Get drive parameter block for specific drive */
|
|
||||||
case 0x5c: /* FLOCK File region locking */
|
case 0x5c: /* FLOCK File region locking */
|
||||||
case 0x5e: /* More Network Functions */
|
case 0x5e: /* More Network Functions */
|
||||||
case 0x5f: /* And Even More Network Functions */
|
|
||||||
default:
|
default:
|
||||||
LOG(LOG_DOSMISC,LOG_ERROR)("DOS:Unhandled call %02X al=%02X. Set al to default of 0",reg_ah,reg_al);
|
LOG(LOG_DOSMISC,LOG_ERROR)("DOS:Unhandled call %02X al=%02X. Set al to default of 0",reg_ah,reg_al);
|
||||||
reg_al=0x00; /* default value */
|
reg_al=0x00; /* default value */
|
||||||
@ -894,7 +938,7 @@ static Bitu DOS_27Handler(void)
|
|||||||
{
|
{
|
||||||
// Terminate & stay resident
|
// Terminate & stay resident
|
||||||
Bit16u para = (reg_dx/16)+((reg_dx % 16)>0);
|
Bit16u para = (reg_dx/16)+((reg_dx % 16)>0);
|
||||||
if (DOS_ResizeMemory(dos.psp,¶)) DOS_Terminate(true);
|
if (DOS_ResizeMemory(dos.psp(),¶)) DOS_Terminate(true);
|
||||||
return CBRET_NONE;
|
return CBRET_NONE;
|
||||||
}
|
}
|
||||||
static Bitu DOS_25Handler(void) {
|
static Bitu DOS_25Handler(void) {
|
||||||
@ -903,9 +947,10 @@ static Bitu DOS_25Handler(void) {
|
|||||||
SETFLAGBIT(CF,true);
|
SETFLAGBIT(CF,true);
|
||||||
}else{
|
}else{
|
||||||
SETFLAGBIT(CF,false);
|
SETFLAGBIT(CF,false);
|
||||||
reg_ax=0;
|
|
||||||
if((reg_cx != 1) ||(reg_dx != 1))
|
if((reg_cx != 1) ||(reg_dx != 1))
|
||||||
LOG(LOG_DOSMISC,LOG_NORMAL)("int 25 called but not as diskdetection");
|
LOG(LOG_DOSMISC,LOG_NORMAL)("int 25 called but not as diskdetection drive %X",reg_al);
|
||||||
|
|
||||||
|
reg_ax=0;
|
||||||
}
|
}
|
||||||
return CBRET_NONE;
|
return CBRET_NONE;
|
||||||
}
|
}
|
||||||
@ -925,7 +970,13 @@ static Bitu DOS_28Handler(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Bitu DOS_29Handler(void) {
|
static Bitu DOS_29Handler(void) {
|
||||||
LOG(LOG_DOSMISC,LOG_ERROR)("int 29 called");
|
static bool int29warn=false;
|
||||||
|
if(!int29warn) {
|
||||||
|
LOG(LOG_DOSMISC,LOG_WARN)("Int 29 called. Redirecting to int 10:0x0e");
|
||||||
|
int29warn=true;
|
||||||
|
}
|
||||||
|
reg_ah=0x0e;
|
||||||
|
CALLBACK_RunRealInt(0x10);
|
||||||
return CBRET_NONE;
|
return CBRET_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -942,31 +993,31 @@ void DOS_ShutDown(Section* sec)
|
|||||||
|
|
||||||
void DOS_Init(Section* sec) {
|
void DOS_Init(Section* sec) {
|
||||||
call_20=CALLBACK_Allocate();
|
call_20=CALLBACK_Allocate();
|
||||||
CALLBACK_Setup(call_20,DOS_20Handler,CB_IRET);
|
CALLBACK_Setup(call_20,DOS_20Handler,CB_IRET,"DOS Int 20");
|
||||||
RealSetVec(0x20,CALLBACK_RealPointer(call_20));
|
RealSetVec(0x20,CALLBACK_RealPointer(call_20));
|
||||||
|
|
||||||
call_21=CALLBACK_Allocate();
|
call_21=CALLBACK_Allocate();
|
||||||
CALLBACK_Setup(call_21,DOS_21Handler,CB_IRET_STI);
|
CALLBACK_Setup(call_21,DOS_21Handler,CB_IRET_STI,"DOS Int 21");
|
||||||
RealSetVec(0x21,CALLBACK_RealPointer(call_21));
|
RealSetVec(0x21,CALLBACK_RealPointer(call_21));
|
||||||
|
|
||||||
call_25=CALLBACK_Allocate();
|
call_25=CALLBACK_Allocate();
|
||||||
CALLBACK_Setup(call_25,DOS_25Handler,CB_RETF);
|
CALLBACK_Setup(call_25,DOS_25Handler,CB_RETF,"DOS Int 25");
|
||||||
RealSetVec(0x25,CALLBACK_RealPointer(call_25));
|
RealSetVec(0x25,CALLBACK_RealPointer(call_25));
|
||||||
|
|
||||||
call_26=CALLBACK_Allocate();
|
call_26=CALLBACK_Allocate();
|
||||||
CALLBACK_Setup(call_26,DOS_26Handler,CB_RETF);
|
CALLBACK_Setup(call_26,DOS_26Handler,CB_RETF,"DOS Int 26");
|
||||||
RealSetVec(0x26,CALLBACK_RealPointer(call_26));
|
RealSetVec(0x26,CALLBACK_RealPointer(call_26));
|
||||||
|
|
||||||
call_27=CALLBACK_Allocate();
|
call_27=CALLBACK_Allocate();
|
||||||
CALLBACK_Setup(call_27,DOS_27Handler,CB_IRET);
|
CALLBACK_Setup(call_27,DOS_27Handler,CB_IRET,"DOS Int 27");
|
||||||
RealSetVec(0x27,CALLBACK_RealPointer(call_27));
|
RealSetVec(0x27,CALLBACK_RealPointer(call_27));
|
||||||
|
|
||||||
call_28=CALLBACK_Allocate();
|
call_28=CALLBACK_Allocate();
|
||||||
CALLBACK_Setup(call_28,DOS_28Handler,CB_IRET);
|
CALLBACK_Setup(call_28,DOS_28Handler,CB_IRET,"DOS Int 28");
|
||||||
RealSetVec(0x28,CALLBACK_RealPointer(call_28));
|
RealSetVec(0x28,CALLBACK_RealPointer(call_28));
|
||||||
|
|
||||||
call_29=CALLBACK_Allocate();
|
call_29=CALLBACK_Allocate();
|
||||||
CALLBACK_Setup(call_29,DOS_29Handler,CB_IRET);
|
CALLBACK_Setup(call_29,DOS_29Handler,CB_IRET,"CON Output Int 29");
|
||||||
RealSetVec(0x29,CALLBACK_RealPointer(call_29));
|
RealSetVec(0x29,CALLBACK_RealPointer(call_29));
|
||||||
|
|
||||||
DOS_SetupFiles(); /* Setup system File tables */
|
DOS_SetupFiles(); /* Setup system File tables */
|
||||||
@ -995,6 +1046,6 @@ void DOS_Init(Section* sec) {
|
|||||||
|
|
||||||
/* case map routine INT 0x21 0x38 */
|
/* case map routine INT 0x21 0x38 */
|
||||||
call_casemap = CALLBACK_Allocate();
|
call_casemap = CALLBACK_Allocate();
|
||||||
CALLBACK_Setup(call_casemap,DOS_CaseMapFunc,CB_RETF);
|
CALLBACK_Setup(call_casemap,DOS_CaseMapFunc,CB_RETF,"DOS CaseMap");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,14 +9,14 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: dos_classes.cpp,v 1.33 2004/01/10 14:03:34 qbix79 Exp $ */
|
/* $Id: dos_classes.cpp,v 1.41 2004/08/04 09:12:53 qbix79 Exp $ */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -64,11 +64,45 @@ void DOS_InfoBlock::SetLocation(Bit16u segment)
|
|||||||
pt=PhysMake(seg,0);
|
pt=PhysMake(seg,0);
|
||||||
/* Clear the initual Block */
|
/* Clear the initual Block */
|
||||||
for(Bitu i=0;i<sizeof(sDIB);i++) mem_writeb(pt+i,0xff);
|
for(Bitu i=0;i<sizeof(sDIB);i++) mem_writeb(pt+i,0xff);
|
||||||
|
|
||||||
|
sSave(sDIB,regCXfrom5e,(Bit16u)0);
|
||||||
|
sSave(sDIB,countLRUcache,(Bit16u)0);
|
||||||
|
sSave(sDIB,countLRUopens,(Bit16u)0);
|
||||||
|
|
||||||
|
sSave(sDIB,protFCBs,(Bit16u)0);
|
||||||
|
sSave(sDIB,specialCodeSeg,(Bit16u)0);
|
||||||
|
sSave(sDIB,joindedDrives,(Bit8u)0);
|
||||||
|
sSave(sDIB,lastdrive,(Bit8u)0x01);//increase this if you add drives to cds-chain
|
||||||
|
|
||||||
|
sSave(sDIB,setverPtr,(Bit32u)0);
|
||||||
|
|
||||||
|
sSave(sDIB,a20FixOfs,(Bit16u)0);
|
||||||
|
sSave(sDIB,pspLastIfHMA,(Bit16u)0);
|
||||||
|
sSave(sDIB,blockDevices,(Bit8u)0);
|
||||||
|
|
||||||
|
sSave(sDIB,bootDrive,(Bit8u)0);
|
||||||
|
sSave(sDIB,useDwordMov,(Bit8u)1);
|
||||||
|
sSave(sDIB,extendedSize,(Bit16u)0x4000); // >16mb
|
||||||
|
|
||||||
|
sSave(sDIB,sharingCount,(Bit16u)0);
|
||||||
|
sSave(sDIB,sharingDelay,(Bit16u)0);
|
||||||
|
|
||||||
|
sSave(sDIB,nulNextDriver,(Bit32u)0xffffffff);
|
||||||
|
sSave(sDIB,nulAttributes,(Bit16u)0x8004);
|
||||||
|
sSave(sDIB,nulStrategy,(Bit32u)0x00000000);
|
||||||
|
sSave(sDIB,nulString[0],(Bit8u)0x4e);
|
||||||
|
sSave(sDIB,nulString[1],(Bit8u)0x55);
|
||||||
|
sSave(sDIB,nulString[2],(Bit8u)0x4c);
|
||||||
|
sSave(sDIB,nulString[3],(Bit8u)0x20);
|
||||||
|
sSave(sDIB,nulString[4],(Bit8u)0x20);
|
||||||
|
sSave(sDIB,nulString[5],(Bit8u)0x20);
|
||||||
|
sSave(sDIB,nulString[6],(Bit8u)0x20);
|
||||||
|
sSave(sDIB,nulString[7],(Bit8u)0x20);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DOS_InfoBlock::SetFirstMCB(Bit16u _firstmcb)
|
void DOS_InfoBlock::SetFirstMCB(Bit16u _firstmcb)
|
||||||
{
|
{
|
||||||
sSave(sDIB,firstMCB,_firstmcb);
|
sSave(sDIB,firstMCB,_firstmcb); //c2woody
|
||||||
}
|
}
|
||||||
|
|
||||||
void DOS_InfoBlock::SetfirstFileTable(RealPt _first_table){
|
void DOS_InfoBlock::SetfirstFileTable(RealPt _first_table){
|
||||||
@ -81,6 +115,26 @@ void DOS_InfoBlock::SetBuffers(Bit16u x,Bit16u y) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DOS_InfoBlock::SetCurDirStruct(Bit32u _curdirstruct)
|
||||||
|
{
|
||||||
|
sSave(sDIB,curDirStructure,_curdirstruct);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DOS_InfoBlock::SetFCBTable(Bit32u _fcbtable)
|
||||||
|
{
|
||||||
|
sSave(sDIB,fcbTable,_fcbtable);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DOS_InfoBlock::SetDeviceChainStart(Bit32u _devchain)
|
||||||
|
{
|
||||||
|
sSave(sDIB,nulNextDriver,_devchain);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DOS_InfoBlock::SetDiskInfoBuffer(Bit32u _dinfobuf)
|
||||||
|
{
|
||||||
|
sSave(sDIB,diskInfoBuffer,_dinfobuf);
|
||||||
|
}
|
||||||
|
|
||||||
RealPt DOS_InfoBlock::GetPointer(void)
|
RealPt DOS_InfoBlock::GetPointer(void)
|
||||||
{
|
{
|
||||||
return RealMake(seg,offsetof(sDIB,firstDPB));
|
return RealMake(seg,offsetof(sDIB,firstDPB));
|
||||||
@ -94,7 +148,7 @@ Bit16u DOS_PSP::rootpsp = 0;
|
|||||||
void DOS_PSP::MakeNew(Bit16u mem_size)
|
void DOS_PSP::MakeNew(Bit16u mem_size)
|
||||||
{
|
{
|
||||||
/* get previous */
|
/* get previous */
|
||||||
DOS_PSP prevpsp(dos.psp);
|
DOS_PSP prevpsp(dos.psp());
|
||||||
/* Clear it first */
|
/* Clear it first */
|
||||||
Bitu i;
|
Bitu i;
|
||||||
for (i=0;i<sizeof(sPSP);i++) mem_writeb(pt+i,0);
|
for (i=0;i<sizeof(sPSP);i++) mem_writeb(pt+i,0);
|
||||||
@ -112,16 +166,16 @@ void DOS_PSP::MakeNew(Bit16u mem_size)
|
|||||||
sSave(sPSP,service[1],0x21);
|
sSave(sPSP,service[1],0x21);
|
||||||
sSave(sPSP,service[2],0xcb);
|
sSave(sPSP,service[2],0xcb);
|
||||||
/* psp and psp-parent */
|
/* psp and psp-parent */
|
||||||
sSave(sPSP,psp_parent,dos.psp);
|
sSave(sPSP,psp_parent,dos.psp());
|
||||||
sSave(sPSP,prev_psp,RealMake(dos.psp,0));
|
sSave(sPSP,prev_psp,0xffffffff);
|
||||||
|
sSave(sPSP,dos_version,0x0005);
|
||||||
/* terminate 22,break 23,crititcal error 24 address stored */
|
/* terminate 22,break 23,crititcal error 24 address stored */
|
||||||
SaveVectors();
|
SaveVectors();
|
||||||
/* Process DTA */
|
|
||||||
sSave(sPSP,dta,RealMake(seg,128));
|
|
||||||
/* FCBs are filled with 0 */
|
/* FCBs are filled with 0 */
|
||||||
// ....
|
// ....
|
||||||
/* Init file pointer and max_files */
|
/* Init file pointer and max_files */
|
||||||
sSave(sPSP,file_table,RealMake(seg,offsetof(sPSP,files[0])));
|
sSave(sPSP,file_table,RealMake(seg,offsetof(sPSP,files)));
|
||||||
sSave(sPSP,max_files,20);
|
sSave(sPSP,max_files,20);
|
||||||
for (i=0;i<20;i++) SetFileHandle(i,0xff);
|
for (i=0;i<20;i++) SetFileHandle(i,0xff);
|
||||||
|
|
||||||
@ -218,7 +272,7 @@ void DOS_PSP::SetCommandTail(RealPt src)
|
|||||||
MEM_BlockCopy(pt+offsetof(sPSP,cmdtail),Real2Phys(src),128);
|
MEM_BlockCopy(pt+offsetof(sPSP,cmdtail),Real2Phys(src),128);
|
||||||
} else { // empty
|
} else { // empty
|
||||||
sSave(sPSP,cmdtail.count,0x00);
|
sSave(sPSP,cmdtail.count,0x00);
|
||||||
mem_writeb(pt+offsetof(sPSP,cmdtail.buffer[0]),0x0d);
|
mem_writeb(pt+offsetof(sPSP,cmdtail.buffer),0x0d);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -403,3 +457,16 @@ void DOS_FCB::GetName(char * fillname) {
|
|||||||
fillname[14]=0;
|
fillname[14]=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DOS_FCB::GetAttr(Bit8u& attr) {
|
||||||
|
if(extended) attr=mem_readb(pt - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DOS_FCB::SetAttr(Bit8u attr) {
|
||||||
|
if(extended) mem_writeb(pt - 1,attr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DOS_SDA::Init() {
|
||||||
|
/* Clear */
|
||||||
|
for(Bitu i=0;i<sizeof(sSDA);i++) mem_writeb(pt+i,0x00);
|
||||||
|
sSave(sSDA,drive_crit_error,0xff);
|
||||||
|
}
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
@ -34,6 +34,27 @@
|
|||||||
static DOS_Device * devices[MAX_DEVICES];
|
static DOS_Device * devices[MAX_DEVICES];
|
||||||
static Bit32u device_count;
|
static Bit32u device_count;
|
||||||
|
|
||||||
|
class device_NUL : public DOS_Device {
|
||||||
|
public:
|
||||||
|
device_NUL() { name="NUL"; };
|
||||||
|
bool Read(Bit8u * data,Bit16u * size) {
|
||||||
|
for(Bitu i = 0; i < *size;i++)
|
||||||
|
data[i]=0;
|
||||||
|
LOG(LOG_IOCTL,LOG_NORMAL)("NUL:READ");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool Write(Bit8u * data,Bit16u * size) {
|
||||||
|
LOG(LOG_IOCTL,LOG_NORMAL)("NUL:WRITE");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool Seek(Bit32u * pos,Bit32u type) {
|
||||||
|
LOG(LOG_IOCTL,LOG_NORMAL)("NUL:SEEK");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
bool Close() { return true; }
|
||||||
|
Bit16u GetInformation(void) { return 0x8004; }
|
||||||
|
};
|
||||||
|
|
||||||
Bit8u DOS_FindDevice(char * name) {
|
Bit8u DOS_FindDevice(char * name) {
|
||||||
/* loop through devices */
|
/* loop through devices */
|
||||||
Bit8u index=0;
|
Bit8u index=0;
|
||||||
@ -73,5 +94,8 @@ void DOS_SetupDevices(void) {
|
|||||||
DOS_Device * newdev;
|
DOS_Device * newdev;
|
||||||
newdev=new device_CON();
|
newdev=new device_CON();
|
||||||
DOS_AddDevice(newdev);
|
DOS_AddDevice(newdev);
|
||||||
|
DOS_Device * newdev2;
|
||||||
|
newdev2=new device_NUL();
|
||||||
|
DOS_AddDevice(newdev2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,16 +9,17 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU Library General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id */
|
/* $Id: dos_execute.cpp,v 1.44 2004/08/04 09:12:53 qbix79 Exp $ */
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
#include "dosbox.h"
|
#include "dosbox.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "dos_inc.h"
|
#include "dos_inc.h"
|
||||||
@ -26,6 +27,8 @@
|
|||||||
#include "callback.h"
|
#include "callback.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
|
char * RunningProgram="DOSBOX";
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
#endif
|
#endif
|
||||||
@ -65,7 +68,7 @@ struct EXE_Header {
|
|||||||
|
|
||||||
|
|
||||||
static void SaveRegisters(void) {
|
static void SaveRegisters(void) {
|
||||||
reg_sp-=20;
|
reg_sp-=18;
|
||||||
mem_writew(SegPhys(ss)+reg_sp+ 0,reg_ax);
|
mem_writew(SegPhys(ss)+reg_sp+ 0,reg_ax);
|
||||||
mem_writew(SegPhys(ss)+reg_sp+ 2,reg_cx);
|
mem_writew(SegPhys(ss)+reg_sp+ 2,reg_cx);
|
||||||
mem_writew(SegPhys(ss)+reg_sp+ 4,reg_dx);
|
mem_writew(SegPhys(ss)+reg_sp+ 4,reg_dx);
|
||||||
@ -87,19 +90,28 @@ static void RestoreRegisters(void) {
|
|||||||
reg_bp=mem_readw(SegPhys(ss)+reg_sp+12);
|
reg_bp=mem_readw(SegPhys(ss)+reg_sp+12);
|
||||||
SegSet16(ds,mem_readw(SegPhys(ss)+reg_sp+14));
|
SegSet16(ds,mem_readw(SegPhys(ss)+reg_sp+14));
|
||||||
SegSet16(es,mem_readw(SegPhys(ss)+reg_sp+16));
|
SegSet16(es,mem_readw(SegPhys(ss)+reg_sp+16));
|
||||||
reg_sp+=20;
|
reg_sp+=18;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern void GFX_SetTitle(Bits cycles,Bits frameskip,bool paused);
|
||||||
|
void DOS_UpdatePSPName(void) {
|
||||||
|
DOS_MCB mcb(dos.psp()-1);
|
||||||
|
static char name[9];
|
||||||
|
mcb.GetFileName(name);
|
||||||
|
if (!strlen(name)) strcpy(name,"DOSBOX");
|
||||||
|
RunningProgram=name;
|
||||||
|
GFX_SetTitle(-1,-1,false);
|
||||||
|
}
|
||||||
|
|
||||||
bool DOS_Terminate(bool tsr) {
|
bool DOS_Terminate(bool tsr) {
|
||||||
|
|
||||||
dos.return_code=reg_al;
|
dos.return_code=reg_al;
|
||||||
dos.return_mode=RETURN_EXIT;
|
dos.return_mode=RETURN_EXIT;
|
||||||
|
|
||||||
Bit16u mempsp = dos.psp;
|
Bit16u mempsp = dos.psp();
|
||||||
|
|
||||||
DOS_PSP curpsp(dos.psp);
|
DOS_PSP curpsp(mempsp);
|
||||||
if (dos.psp==curpsp.GetParent()) return true;
|
if (mempsp==curpsp.GetParent()) return true;
|
||||||
/* Free Files owned by process */
|
/* Free Files owned by process */
|
||||||
if (!tsr) curpsp.CloseFiles();
|
if (!tsr) curpsp.CloseFiles();
|
||||||
|
|
||||||
@ -108,10 +120,9 @@ bool DOS_Terminate(bool tsr) {
|
|||||||
/* Restore vector 22,23,24 */
|
/* Restore vector 22,23,24 */
|
||||||
curpsp.RestoreVectors();
|
curpsp.RestoreVectors();
|
||||||
/* Set the parent PSP */
|
/* Set the parent PSP */
|
||||||
dos.psp = curpsp.GetParent();
|
dos.psp(curpsp.GetParent());
|
||||||
DOS_PSP parentpsp(curpsp.GetParent());
|
DOS_PSP parentpsp(curpsp.GetParent());
|
||||||
/* Restore the DTA of the parent psp */
|
|
||||||
dos.dta = parentpsp.GetDTA();
|
|
||||||
/* Restore the SS:SP to the previous one */
|
/* Restore the SS:SP to the previous one */
|
||||||
SegSet16(ss,RealSeg(parentpsp.GetStack()));
|
SegSet16(ss,RealSeg(parentpsp.GetStack()));
|
||||||
reg_sp = RealOff(parentpsp.GetStack());
|
reg_sp = RealOff(parentpsp.GetStack());
|
||||||
@ -123,15 +134,13 @@ bool DOS_Terminate(bool tsr) {
|
|||||||
mem_writew(SegPhys(ss)+reg_sp+4,0x200); //stack isn't preserved
|
mem_writew(SegPhys(ss)+reg_sp+4,0x200); //stack isn't preserved
|
||||||
// Free memory owned by process
|
// Free memory owned by process
|
||||||
if (!tsr) DOS_FreeProcessMemory(mempsp);
|
if (!tsr) DOS_FreeProcessMemory(mempsp);
|
||||||
|
DOS_UpdatePSPName();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static bool MakeEnv(char * name,Bit16u * segment) {
|
static bool MakeEnv(char * name,Bit16u * segment) {
|
||||||
|
|
||||||
/* If segment to copy environment is 0 copy the caller's environment */
|
/* If segment to copy environment is 0 copy the caller's environment */
|
||||||
DOS_PSP psp(dos.psp);
|
DOS_PSP psp(dos.psp());
|
||||||
PhysPt envread,envwrite;
|
PhysPt envread,envwrite;
|
||||||
Bit16u envsize=1;
|
Bit16u envsize=1;
|
||||||
bool parentenv=true;
|
bool parentenv=true;
|
||||||
@ -173,8 +182,7 @@ static bool MakeEnv(char * name,Bit16u * segment) {
|
|||||||
} else return false;
|
} else return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DOS_NewPSP(Bit16u segment, Bit16u size)
|
bool DOS_NewPSP(Bit16u segment, Bit16u size) {
|
||||||
{
|
|
||||||
DOS_PSP psp(segment);
|
DOS_PSP psp(segment);
|
||||||
psp.MakeNew(size);
|
psp.MakeNew(size);
|
||||||
DOS_PSP psp_parent(psp.GetParent());
|
DOS_PSP psp_parent(psp.GetParent());
|
||||||
@ -182,8 +190,7 @@ bool DOS_NewPSP(Bit16u segment, Bit16u size)
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool DOS_ChildPSP(Bit16u segment, Bit16u size)
|
bool DOS_ChildPSP(Bit16u segment, Bit16u size) {
|
||||||
{
|
|
||||||
DOS_PSP psp(segment);
|
DOS_PSP psp(segment);
|
||||||
psp.MakeNew(size);
|
psp.MakeNew(size);
|
||||||
DOS_PSP psp_parent(psp.GetParent());
|
DOS_PSP psp_parent(psp.GetParent());
|
||||||
@ -194,7 +201,6 @@ bool DOS_ChildPSP(Bit16u segment, Bit16u size)
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void SetupPSP(Bit16u pspseg,Bit16u memsize,Bit16u envseg) {
|
static void SetupPSP(Bit16u pspseg,Bit16u memsize,Bit16u envseg) {
|
||||||
|
|
||||||
/* Fix the PSP for psp and environment MCB's */
|
/* Fix the PSP for psp and environment MCB's */
|
||||||
DOS_MCB mcb((Bit16u)(pspseg-1));
|
DOS_MCB mcb((Bit16u)(pspseg-1));
|
||||||
mcb.SetPSPSeg(pspseg);
|
mcb.SetPSPSeg(pspseg);
|
||||||
@ -204,31 +210,14 @@ static void SetupPSP(Bit16u pspseg,Bit16u memsize,Bit16u envseg) {
|
|||||||
DOS_PSP psp(pspseg);
|
DOS_PSP psp(pspseg);
|
||||||
psp.MakeNew(memsize);
|
psp.MakeNew(memsize);
|
||||||
psp.SetEnvironment(envseg);
|
psp.SetEnvironment(envseg);
|
||||||
/* Copy file handles //QBIX::ALWAYS COPY BUT LEFT ORIGINAL INCASE OF MISTAKES
|
|
||||||
/* if (DOS_PSP::rootpsp!=dos.psp) { */
|
/* Copy file handles */
|
||||||
// TODO: Improve this
|
DOS_PSP oldpsp(dos.psp());
|
||||||
// If prog wasnt started from commandline copy file table (California Games 2)
|
|
||||||
/* DOS_PSP oldpsp(dos.psp);
|
|
||||||
psp.CopyFileTable(&oldpsp);
|
|
||||||
} else {
|
|
||||||
psp.SetFileHandle(STDIN ,DOS_FindDevice("CON"));
|
|
||||||
psp.SetFileHandle(STDOUT,DOS_FindDevice("CON"));
|
|
||||||
psp.SetFileHandle(STDERR,DOS_FindDevice("CON"));
|
|
||||||
psp.SetFileHandle(STDAUX,DOS_FindDevice("CON"));
|
|
||||||
psp.SetFileHandle(STDNUL,DOS_FindDevice("CON"));
|
|
||||||
psp.SetFileHandle(STDPRN,DOS_FindDevice("CON"));
|
|
||||||
} */
|
|
||||||
/* Save old DTA in psp */
|
|
||||||
DOS_PSP oldpsp(dos.psp);
|
|
||||||
psp.CopyFileTable(&oldpsp,true);
|
psp.CopyFileTable(&oldpsp,true);
|
||||||
|
|
||||||
psp.SetDTA(dos.dta);
|
|
||||||
/* Setup the DTA */
|
|
||||||
dos.dta=RealMake(pspseg,0x80);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetupCMDLine(Bit16u pspseg,DOS_ParamBlock & block)
|
static void SetupCMDLine(Bit16u pspseg,DOS_ParamBlock & block) {
|
||||||
{
|
|
||||||
DOS_PSP psp(pspseg);
|
DOS_PSP psp(pspseg);
|
||||||
// if cmdtail==0 it will inited as empty in SetCommandTail
|
// if cmdtail==0 it will inited as empty in SetCommandTail
|
||||||
psp.SetCommandTail(block.exec.cmdtail);
|
psp.SetCommandTail(block.exec.cmdtail);
|
||||||
@ -263,14 +252,8 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) {
|
|||||||
if (len<sizeof(EXE_Header)) iscom=true;
|
if (len<sizeof(EXE_Header)) iscom=true;
|
||||||
if ((head.signature!=MAGIC1) && (head.signature!=MAGIC2)) iscom=true;
|
if ((head.signature!=MAGIC1) && (head.signature!=MAGIC2)) iscom=true;
|
||||||
else {
|
else {
|
||||||
headersize=head.headersize*16;
|
headersize = head.headersize*16;
|
||||||
if (head.extrabytes) {
|
|
||||||
imagesize = (head.pages-1)*512-headersize;
|
|
||||||
imagesize += head.extrabytes % 512;
|
|
||||||
} else
|
|
||||||
imagesize = head.pages*512-headersize;
|
imagesize = head.pages*512-headersize;
|
||||||
|
|
||||||
// always load st least 512 Bytes (dos cache/dos bug?)
|
|
||||||
if (imagesize+headersize<512) imagesize = 512-headersize;
|
if (imagesize+headersize<512) imagesize = 512-headersize;
|
||||||
}
|
}
|
||||||
if (flags!=OVERLAY) {
|
if (flags!=OVERLAY) {
|
||||||
@ -298,10 +281,14 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) {
|
|||||||
else memsize=maxsize;
|
else memsize=maxsize;
|
||||||
if (!DOS_AllocateMemory(&pspseg,&memsize)) E_Exit("DOS:Exec error in memory");
|
if (!DOS_AllocateMemory(&pspseg,&memsize)) E_Exit("DOS:Exec error in memory");
|
||||||
loadseg=pspseg+16;
|
loadseg=pspseg+16;
|
||||||
|
if ((!iscom) & (head.minmemory == 0) & (head.maxmemory == 0))
|
||||||
|
loadseg = (0x9e000 - imagesize)/16; //c2woody
|
||||||
|
|
||||||
} else loadseg=block.overlay.loadseg;
|
} else loadseg=block.overlay.loadseg;
|
||||||
/* Load the executable */
|
/* Load the executable */
|
||||||
Bit8u * loadbuf=(Bit8u *)new Bit8u[0x10000];
|
Bit8u * loadbuf=(Bit8u *)new Bit8u[0x10000];
|
||||||
loadaddress=PhysMake(loadseg,0);
|
loadaddress=PhysMake(loadseg,0);
|
||||||
|
|
||||||
if (iscom) { /* COM Load 64k - 256 bytes max */
|
if (iscom) { /* COM Load 64k - 256 bytes max */
|
||||||
pos=0;DOS_SeekFile(fhandle,&pos,DOS_SEEK_SET);
|
pos=0;DOS_SeekFile(fhandle,&pos,DOS_SEEK_SET);
|
||||||
readsize=0xffff-256;
|
readsize=0xffff-256;
|
||||||
@ -341,7 +328,6 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) {
|
|||||||
SetupPSP(pspseg,memsize,envseg);
|
SetupPSP(pspseg,memsize,envseg);
|
||||||
SetupCMDLine(pspseg,block);
|
SetupCMDLine(pspseg,block);
|
||||||
};
|
};
|
||||||
|
|
||||||
CALLBACK_SCF(false); /* Carry flag cleared for caller if successfull */
|
CALLBACK_SCF(false); /* Carry flag cleared for caller if successfull */
|
||||||
if (flags==OVERLAY) return true; /* Everything done for overlays */
|
if (flags==OVERLAY) return true; /* Everything done for overlays */
|
||||||
RealPt csip,sssp;
|
RealPt csip,sssp;
|
||||||
@ -355,12 +341,13 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (flags==LOAD) {
|
if (flags==LOAD) {
|
||||||
DOS_PSP callpsp(dos.psp);
|
DOS_PSP callpsp(dos.psp());
|
||||||
/* Save the SS:SP on the PSP of calling program */
|
/* Save the SS:SP on the PSP of calling program */
|
||||||
callpsp.SetStack(RealMakeSeg(ss,reg_sp));
|
callpsp.SetStack(RealMakeSeg(ss,reg_sp));
|
||||||
/* Switch the psp's */
|
/* Switch the psp's */
|
||||||
dos.psp=pspseg;
|
dos.psp(pspseg);
|
||||||
|
DOS_PSP newpsp(dos.psp());
|
||||||
|
dos.dta(RealMake(newpsp.GetSegment(),0x80));
|
||||||
block.exec.initsssp = sssp;
|
block.exec.initsssp = sssp;
|
||||||
block.exec.initcsip = csip;
|
block.exec.initcsip = csip;
|
||||||
block.SaveData();
|
block.SaveData();
|
||||||
@ -371,14 +358,13 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) {
|
|||||||
/* Get Caller's program CS:IP of the stack and set termination address to that */
|
/* Get Caller's program CS:IP of the stack and set termination address to that */
|
||||||
RealSetVec(0x22,RealMake(mem_readw(SegPhys(ss)+reg_sp+2),mem_readw(SegPhys(ss)+reg_sp)));
|
RealSetVec(0x22,RealMake(mem_readw(SegPhys(ss)+reg_sp+2),mem_readw(SegPhys(ss)+reg_sp)));
|
||||||
SaveRegisters();
|
SaveRegisters();
|
||||||
DOS_PSP callpsp(dos.psp);
|
DOS_PSP callpsp(dos.psp());
|
||||||
/* Save the SS:SP on the PSP of calling program */
|
/* Save the SS:SP on the PSP of calling program */
|
||||||
callpsp.SetStack(RealMakeSeg(ss,reg_sp));
|
callpsp.SetStack(RealMakeSeg(ss,reg_sp));
|
||||||
/* Switch the psp's and set new DTA */
|
/* Switch the psp's and set new DTA */
|
||||||
dos.psp=pspseg;
|
dos.psp(pspseg);
|
||||||
DOS_PSP newpsp(dos.psp);
|
DOS_PSP newpsp(dos.psp());
|
||||||
newpsp.SetDTA(dos.dta); /* Original: change this and line below. This way seems better(zone66 and unpack) */
|
dos.dta(RealMake(newpsp.GetSegment(),0x80));
|
||||||
//dos.dta=newpsp.GetDTA();
|
|
||||||
/* save vectors */
|
/* save vectors */
|
||||||
newpsp.SaveVectors();
|
newpsp.SaveVectors();
|
||||||
/* copy fcbs */
|
/* copy fcbs */
|
||||||
@ -399,6 +385,24 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) {
|
|||||||
/* Started from debug.com, then set breakpoint at start */
|
/* Started from debug.com, then set breakpoint at start */
|
||||||
DEBUG_CheckExecuteBreakpoint(RealSeg(csip),RealOff(csip));
|
DEBUG_CheckExecuteBreakpoint(RealSeg(csip),RealOff(csip));
|
||||||
#endif
|
#endif
|
||||||
|
/* Add the filename to PSP and environment MCB's */
|
||||||
|
char stripname[8];Bitu index=0;
|
||||||
|
while (char chr=*name++) {
|
||||||
|
switch (chr) {
|
||||||
|
case ':':case '\\':case '/':index=0;break;
|
||||||
|
default:if (index<8) stripname[index++]=toupper(chr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
index=0;
|
||||||
|
while (index<8) {
|
||||||
|
if (stripname[index]=='.') break;
|
||||||
|
if (!stripname[index]) break;
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
memset(&stripname[index],0,8-index);
|
||||||
|
DOS_MCB pspmcb(dos.psp()-1);
|
||||||
|
pspmcb.SetFileName(stripname);
|
||||||
|
DOS_UpdatePSPName();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user