mirror of
https://github.com/retro100/dosbox-wii.git
synced 2024-12-25 01:51:49 +01:00
DOSBox 0.58
This commit is contained in:
parent
0e247f1518
commit
d82f029c50
24
ChangeLog
24
ChangeLog
@ -1,3 +1,27 @@
|
||||
0.58
|
||||
- fixed date and time issues with fcbs
|
||||
- added more commands to the internal Shell
|
||||
- corrected config system when a old configfile was used
|
||||
- fixed cga put and get pixel
|
||||
- fixed some vga register getting reset to wrong values
|
||||
- improved support for foreign keyboards
|
||||
- improved joystick support
|
||||
- made dosbox multithreaded again
|
||||
- lot's of soundblaster fixes
|
||||
- dma fixes
|
||||
- cdrom support
|
||||
- midi support
|
||||
- added scale2x
|
||||
- reenabled screenshot support
|
||||
- joystick support fixes
|
||||
- mouse improvements
|
||||
- support for writing wavefiles
|
||||
- added directory cache and longfilename support (longfilenames will be mangled)
|
||||
- mouse fixes
|
||||
- date and time updates at z:\
|
||||
- added (partial) direct disk support. (works probably only if directory is mounted under a:\)
|
||||
- added support for env variables. (must be set before starting dosbox: DOSBOX_SECTION_PROPERTY=value
|
||||
like DOSBOX_SBLASTER_IRQ=1)
|
||||
0.57
|
||||
- added support for command /C
|
||||
- fixed all fcb-write functions
|
||||
|
13
INSTALL
13
INSTALL
@ -1,6 +1,3 @@
|
||||
First of all if you are running a non-x86 machine this will not work,
|
||||
code only works for big-endian machines for now :)
|
||||
|
||||
Things needed for compilation.
|
||||
|
||||
SDL
|
||||
@ -12,7 +9,7 @@ Curses
|
||||
For win32 get pdcurses at http://pdcurses.sourceforge.net
|
||||
|
||||
Libpng
|
||||
Needed for the screenshots.
|
||||
Needed for the screenshots. (--enable-shots when configuring dosbox)
|
||||
For win32 get libpng from http://www.sourceforge.net/projects/gnuwin32
|
||||
|
||||
Zlib
|
||||
@ -27,8 +24,12 @@ For building on unix systems.
|
||||
If you are building from the cvs run ./autogen.sh first before doing the following.
|
||||
|
||||
1. ./configure
|
||||
2. Check settings.h for some setup options.
|
||||
3. make
|
||||
2. make
|
||||
|
||||
In step 1 you could add the following switches --enable-shots this will
|
||||
enable the screenshot facility, also --enable-debug is a valid switch. This
|
||||
will enable the internal debugger. (It can be started by pressing - on the
|
||||
numeric keyboard)
|
||||
|
||||
Check the src subdir for the binary.
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
# Main Makefile for DOSBox
|
||||
|
||||
EXTRA_DIST = settings.h autogen.sh
|
||||
SUBDIRS = src include visualc
|
||||
EXTRA_DIST = autogen.sh
|
||||
SUBDIRS = src include visualc docs
|
||||
|
||||
|
||||
|
||||
|
23
Makefile.in
23
Makefile.in
@ -1,4 +1,4 @@
|
||||
# Makefile.in generated by automake 1.6.1 from Makefile.am.
|
||||
# Makefile.in generated by automake 1.6.3 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
|
||||
@ -51,6 +51,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = @program_transform_name@
|
||||
@ -66,6 +67,8 @@ host_triplet = @host@
|
||||
EXEEXT = @EXEEXT@
|
||||
OBJEXT = @OBJEXT@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
ALSA_CFLAGS = @ALSA_CFLAGS@
|
||||
ALSA_LIBS = @ALSA_LIBS@
|
||||
AMTAR = @AMTAR@
|
||||
AWK = @AWK@
|
||||
CC = @CC@
|
||||
@ -84,8 +87,8 @@ am__include = @am__include@
|
||||
am__quote = @am__quote@
|
||||
install_sh = @install_sh@
|
||||
|
||||
EXTRA_DIST = settings.h autogen.sh
|
||||
SUBDIRS = src include visualc
|
||||
EXTRA_DIST = autogen.sh
|
||||
SUBDIRS = src include visualc docs
|
||||
subdir = .
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
@ -106,6 +109,9 @@ all: config.h
|
||||
$(MAKE) $(AM_MAKEFLAGS) all-recursive
|
||||
|
||||
.SUFFIXES:
|
||||
|
||||
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
|
||||
configure.lineno
|
||||
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
|
||||
cd $(top_srcdir) && \
|
||||
$(AUTOMAKE) --gnits Makefile
|
||||
@ -135,7 +141,7 @@ $(srcdir)/config.h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4)
|
||||
touch $(srcdir)/config.h.in
|
||||
|
||||
distclean-hdr:
|
||||
-rm -f config.h
|
||||
-rm -f config.h stamp-h1
|
||||
uninstall-info-am:
|
||||
|
||||
# This directory's subdirectories are mostly independent; you can cd
|
||||
@ -254,7 +260,7 @@ distdir: $(DISTFILES)
|
||||
fi
|
||||
$(am__remove_distdir)
|
||||
mkdir $(distdir)
|
||||
@for file in $(DISTFILES); do \
|
||||
@list='$(DISTFILES)'; for file in $$list; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
|
||||
@ -364,7 +370,7 @@ mostlyclean-generic:
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]*
|
||||
-rm -f Makefile $(CONFIG_CLEAN_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@ -374,7 +380,7 @@ clean: clean-recursive
|
||||
clean-am: clean-generic mostlyclean-am
|
||||
|
||||
distclean: distclean-recursive
|
||||
-rm -f config.status config.cache config.log
|
||||
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
|
||||
distclean-am: clean-am distclean-generic distclean-hdr distclean-tags
|
||||
|
||||
dvi: dvi-recursive
|
||||
@ -396,7 +402,8 @@ install-man:
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-recursive
|
||||
|
||||
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
|
||||
-rm -rf autom4te.cache
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-recursive
|
||||
|
22
NEWS
22
NEWS
@ -1,3 +1,25 @@
|
||||
0.58
|
||||
- fixed date and time issues with fcbs
|
||||
- added more commands to the internal Shell
|
||||
- corrected config system when a old configfile was used
|
||||
- fixed cga put and get pixel
|
||||
- fixed some vga register getting reset to wrong values
|
||||
- improved support for foreign keyboards
|
||||
- improved joystick support
|
||||
- made dosbox multithreaded again
|
||||
- lot's of soundblaster fixes
|
||||
- dma fixes
|
||||
- cdrom support
|
||||
- midi support
|
||||
- added scale2x
|
||||
- reenabled screenshot support
|
||||
- joystick support fixes
|
||||
- mouse improvements
|
||||
- support for writing wavefiles
|
||||
- added directory cache and longfilename support (longfilenames will be mangled)
|
||||
- mouse fixes
|
||||
|
||||
|
||||
0.57
|
||||
- added support for command /C
|
||||
- fixed all fcb-write functions
|
||||
|
155
README
155
README
@ -1,19 +1,23 @@
|
||||
DOSBox v0.57
|
||||
DOSBox v0.58
|
||||
|
||||
Usage:
|
||||
======
|
||||
|
||||
With the new internal shell I've changed the command line a bit, so let's just give some
|
||||
examples of what you can do now.
|
||||
With the new internal shell,we've changed the command line a bit,
|
||||
so let's just give some examples of what you can do now.
|
||||
|
||||
dosbox
|
||||
With nothing on the command line you'll end up on the internal drive and from there you
|
||||
can mount directories as drives.
|
||||
With nothing on the command line you'll end up on the internal drive and
|
||||
from there you can mount directories as drives.
|
||||
dosbox [filename/directory]
|
||||
If dosbox detects a directory it'll mount that as c:\ and then start the shell.
|
||||
If dosbox doesn't detect a directory it'll assume you mean an executable this can be
|
||||
.bat .com .exe. Doesn't need to have extension included. Then it'll strip the directory
|
||||
from the filename and mount that as c:\ and then run the file.
|
||||
If dosbox detects a directory it'll mount that as the C: drive
|
||||
and then start the shell from c:\.
|
||||
If dosbox doesn't detect a directory it'll assume you mean an executable.
|
||||
This can be .bat .com .exe. Doesn't need to have extension included.
|
||||
It will mount the directory the file is in as the C: drive.
|
||||
Then start up the shell which will start the file.
|
||||
|
||||
There also are a couple of command line switches.
|
||||
|
||||
dosbox -fullscreen
|
||||
starts dosbox in fullscreen mode.
|
||||
@ -22,64 +26,81 @@ dosbox -conf file
|
||||
dosbox -lang file
|
||||
loads file as a languagefile.
|
||||
|
||||
You can also add commands to be executed before the main program starts. Or you can use them
|
||||
to start the program.
|
||||
You can also add commands to be executed before the main program starts.
|
||||
Or you can use them to start the program.
|
||||
To add commands use the -c command line switch.
|
||||
For example
|
||||
dosbox c:\atlantis\atlantis.exe -c "MOUNT D C:\SAVES" "SET TEST=blah"
|
||||
This would mount c:\atlanis as c:\ and run atlantis.exe from that directory but before it
|
||||
does that it would first mount C:\SAVES as the D drive and set the environment variable test to blah.
|
||||
|
||||
Dragging files or directories onto the DOSBox executable should also work.
|
||||
For example:
|
||||
|
||||
dosbox c:\atlantis\atlantis.exe -c "MOUNT D C:\SAVES"
|
||||
This would mount c:\atlanis as c:\ and run atlantis.exe.
|
||||
Before it does that it would first mount C:\SAVES as the D drive.
|
||||
|
||||
In Windows you can also drag directories/files on the dosbox executable.
|
||||
|
||||
Internal Programs:
|
||||
==================
|
||||
|
||||
MOUNT
|
||||
Program to mount local directories as drives inside DOSBox.
|
||||
The option -t specifies the media: dir = harddisk, floppy = floppy drive.
|
||||
The option -size specifies the size.
|
||||
For example to mount c:\floppy as a floppy : mount -t floppy a c:\floppy
|
||||
The option -t <type> specifies the media: Where <type> can be.
|
||||
dir = harddisk
|
||||
floppy = floppy drive
|
||||
cdrom = cdrom drive
|
||||
|
||||
The option -cd lists all found cdrom drives and their id.
|
||||
The option -usecd [x] forces to use the cdrom number x (id as shown in list -cd)
|
||||
|
||||
The option -aspi forces to use aspi driver
|
||||
(only valid if mounting a cdrom and on Windows systems with ASPI-Layer).
|
||||
The option -ioctl forces to use ioctl functions
|
||||
(only valid if mounting a cdrom and on Win2000/XP/NT systems).
|
||||
|
||||
For example to mount c:\floppy as a floppy : mount a c:\floppy -t floppy
|
||||
For example to mount system cdrom drive e as cdrom drive d in dosbox
|
||||
mount d e:\ -t cdrom
|
||||
For example to mount system cdrom drive at mountpoint /media/cdrom as cdrom
|
||||
drive d in dosbox
|
||||
mount d /media/cdrom -t cdrom -usecd 0
|
||||
|
||||
It is also possible to mount a directory as cdrom, but it's limited.
|
||||
|
||||
MEM
|
||||
Program to display the amount of free memory
|
||||
|
||||
CONFIG
|
||||
Utility for generating a configfile with the current settings and for generating the languagefile.
|
||||
Utility for generating a config file and language file.
|
||||
The option -writeconf filename is used to write the current config settings.
|
||||
The option -writelang filename is used to write the current language strings.
|
||||
|
||||
UPCASE <Linux Version only>
|
||||
Utility to convert all files subdirectories of a local directory into upcase so DOSBox can use that directory
|
||||
for mounting. This tool can be quite dangerous if used unproperly. You have been warned.
|
||||
For more information use the the /? command line switch with the programs.
|
||||
|
||||
To get more information about how to use one these programs use the the /? command line switch.
|
||||
|
||||
The Configfile:
|
||||
The Config File:
|
||||
===============
|
||||
A configfile can be generated by CONFIG.COM. You can edit it to customize DOSBox.
|
||||
The file is divided in several sections (the names got [] around it). Some sections have options which you can set.
|
||||
A config file can be generated by CONFIG.COM, edit it to customize DOSBox.
|
||||
The file is divided in several sections (the names got [] around it).
|
||||
Some sections have options which you can set.
|
||||
# and % indicate commentlines.
|
||||
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.
|
||||
For example in the section sblaster you can change the irq of the soundblaster and disable/enable the
|
||||
adlib emulation.
|
||||
|
||||
The Languagefile:
|
||||
The Language File:
|
||||
=================
|
||||
A languagefile can be generated by CONFIG.COM. If you read it you will understand how to change it.
|
||||
Start Dosbox with -lang switch to use your language file or enter the location of the languagefile
|
||||
in the configfile.(section:[dosbox] language=full path to languagefile.)
|
||||
A language file can be generated by CONFIG.COM.
|
||||
Read it and you will hopefuly understand how to change it.
|
||||
Start Dosbox with -lang switch to use your new language file
|
||||
Or you can setup the filename in the config file in the [dosbox] section.
|
||||
There's a language= entry that can be changed with the filename.
|
||||
|
||||
Special Keys:
|
||||
=============
|
||||
|
||||
ALT-ENTER Go full screen and back.
|
||||
CTRL-F5 Save a screenshot
|
||||
CTRL-F7 Decrease frameskip
|
||||
CTRL-F8 Increase frameskip
|
||||
CTRL-F9 Go full screen and back.
|
||||
CTRL-F5 Save a screenshot.
|
||||
CTRL-F6 Start/Stop recording sound output to a wave file.
|
||||
CTRL-F7 Decrease frameskip.
|
||||
CTRL-F8 Increase frameskip.
|
||||
CTRL-F9 Kill dosbox.
|
||||
CTRL-F10 Capture/Release the mouse.
|
||||
CTRL-F11 Slowdown emulation.
|
||||
CTRL-F12 Speedup emulation.
|
||||
@ -93,21 +114,55 @@ of games written for an 286 machine.
|
||||
FAQ:
|
||||
====
|
||||
|
||||
1.Q: I've got a Z instead of a C at the prompt.
|
||||
A: In DOSBox you can mount directories as drives
|
||||
in win32: mount c D:\ would give you an C in DOSBox which points
|
||||
at D:\ in win32
|
||||
in linux: mount c /home/username would give you and C in DOSBox
|
||||
which points at /home/username in Linux
|
||||
Q: I've got a Z instead of a C at the prompt.
|
||||
A: In DOSBox you can mount directories as drives
|
||||
in win32: mount c D:\ would give you an C in DOSBox which points
|
||||
at D:\ in win32
|
||||
in linux: mount c /home/username would give you and C in DOSBox
|
||||
which points at /home/username in Linux
|
||||
|
||||
2.Q: The window is too small.
|
||||
A: When you mouse touches the edges of the DOSBox screen you can click and drag it to
|
||||
the size you prefer.
|
||||
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.
|
||||
|
||||
3.Q: The mouse(cursor) acts weird. (eg only updated when you press the mousebutton)
|
||||
A: Lock the mouse with ctrl-F10. It should then behave the way you expect it to do.
|
||||
Q: The sound stutters.
|
||||
A: Your 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.
|
||||
|
||||
|
||||
For more questions check the site/forum.
|
||||
|
||||
|
||||
To run resource-demanding games:
|
||||
===============================
|
||||
|
||||
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
|
||||
you'll be limited by the power of your actual CPU. You can see how much free
|
||||
time your true CPU has by looking at the Task Manager in Windows 2000/XP and
|
||||
the System Monitor in Windows 95/98/ME. Once 100% of your real CPU time is
|
||||
used there is no further way to speed up DOSBox unless you reduce the load
|
||||
generated by the non-CPU parts of DOSBox.
|
||||
|
||||
So:
|
||||
|
||||
Close every program but DOSBox
|
||||
|
||||
Overclock DOSBox until 100% of your CPU is used (use the utilities above to
|
||||
check)
|
||||
|
||||
Since VGA emulation is the most demanding part of DOSBox in terms of actual
|
||||
CPU usage, we'll start here. Increase the number of frames skipped (in
|
||||
increments of one) by pressing CRTL+F8. Your CPU usage should decrease.
|
||||
Go back one step and repeat this until the game runs fast enough for you.
|
||||
Please note that this is a trade off: you lose in fluidity of video what you
|
||||
gain in speed
|
||||
|
||||
You can also try to disable the sound through the setup utility of the game
|
||||
to further reduce load on your CPU.
|
||||
|
||||
4. Check the site/forum.
|
||||
|
||||
Building your own Version DOSBox:
|
||||
=================================
|
||||
|
3
THANKS
3
THANKS
@ -3,7 +3,10 @@ We would like to thank:
|
||||
|
||||
Vlad R. of the vdmsound project for excellent sound blaster info.
|
||||
Tatsuyuki Satoh of the Mame Team for making an excellent FM emulator.
|
||||
Jarek Burczynski for the new OPL emulator.
|
||||
|
||||
The Bochs and DOSemu projects which I used for information.
|
||||
Freedos for ideas in making my shell.
|
||||
|
||||
All the people who submitted a bug.
|
||||
The Beta Testers.
|
||||
|
163
acinclude.m4
163
acinclude.m4
@ -160,9 +160,155 @@ int main (int argc, char *argv[])
|
||||
rm -f conf.sdltest
|
||||
])
|
||||
|
||||
dnl Configure Paths for Alsa
|
||||
dnl Some modifications by Richard Boulton <richard-alsa@tartarus.org>
|
||||
dnl Christopher Lansdown <lansdoct@cs.alfred.edu>
|
||||
dnl Jaroslav Kysela <perex@suse.cz>
|
||||
dnl Last modification: alsa.m4,v 1.22 2002/05/27 11:14:20 tiwai Exp
|
||||
dnl AM_PATH_ALSA([MINIMUM-VERSION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
|
||||
dnl Test for libasound, and define ALSA_CFLAGS and ALSA_LIBS as appropriate.
|
||||
dnl enables arguments --with-alsa-prefix=
|
||||
dnl --with-alsa-enc-prefix=
|
||||
dnl --disable-alsatest (this has no effect, as yet)
|
||||
dnl
|
||||
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
|
||||
AC_DEFUN(AM_PATH_ALSA,
|
||||
[dnl Save the original CFLAGS, LDFLAGS, and LIBS
|
||||
alsa_save_CFLAGS="$CFLAGS"
|
||||
alsa_save_LDFLAGS="$LDFLAGS"
|
||||
alsa_save_LIBS="$LIBS"
|
||||
alsa_found=yes
|
||||
|
||||
dnl
|
||||
dnl Get the cflags and libraries for alsa
|
||||
dnl
|
||||
AC_ARG_WITH(alsa-prefix,
|
||||
[ --with-alsa-prefix=PFX Prefix where Alsa library is installed(optional)],
|
||||
[alsa_prefix="$withval"], [alsa_prefix=""])
|
||||
|
||||
AC_ARG_WITH(alsa-inc-prefix,
|
||||
[ --with-alsa-inc-prefix=PFX Prefix where include libraries are (optional)],
|
||||
[alsa_inc_prefix="$withval"], [alsa_inc_prefix=""])
|
||||
|
||||
dnl FIXME: this is not yet implemented
|
||||
AC_ARG_ENABLE(alsatest,
|
||||
[ --disable-alsatest Do not try to compile and run a test Alsa program],
|
||||
[enable_alsatest=no],
|
||||
[enable_alsatest=yes])
|
||||
|
||||
dnl Add any special include directories
|
||||
AC_MSG_CHECKING(for ALSA CFLAGS)
|
||||
if test "$alsa_inc_prefix" != "" ; then
|
||||
ALSA_CFLAGS="$ALSA_CFLAGS -I$alsa_inc_prefix"
|
||||
CFLAGS="$CFLAGS -I$alsa_inc_prefix"
|
||||
fi
|
||||
AC_MSG_RESULT($ALSA_CFLAGS)
|
||||
|
||||
dnl add any special lib dirs
|
||||
AC_MSG_CHECKING(for ALSA LDFLAGS)
|
||||
if test "$alsa_prefix" != "" ; then
|
||||
ALSA_LIBS="$ALSA_LIBS -L$alsa_prefix"
|
||||
LDFLAGS="$LDFLAGS $ALSA_LIBS"
|
||||
fi
|
||||
|
||||
dnl add the alsa library
|
||||
ALSA_LIBS="$ALSA_LIBS -lasound -lm -ldl -lpthread"
|
||||
LIBS=`echo $LIBS | sed 's/-lm//'`
|
||||
LIBS=`echo $LIBS | sed 's/-ldl//'`
|
||||
LIBS=`echo $LIBS | sed 's/-lpthread//'`
|
||||
LIBS=`echo $LIBS | sed 's/ //'`
|
||||
LIBS="$ALSA_LIBS $LIBS"
|
||||
AC_MSG_RESULT($ALSA_LIBS)
|
||||
|
||||
dnl Check for a working version of libasound that is of the right version.
|
||||
min_alsa_version=ifelse([$1], ,0.1.1,$1)
|
||||
AC_MSG_CHECKING(for libasound headers version >= $min_alsa_version)
|
||||
no_alsa=""
|
||||
alsa_min_major_version=`echo $min_alsa_version | \
|
||||
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
|
||||
alsa_min_minor_version=`echo $min_alsa_version | \
|
||||
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
|
||||
alsa_min_micro_version=`echo $min_alsa_version | \
|
||||
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
|
||||
|
||||
AC_LANG_SAVE
|
||||
AC_LANG_C
|
||||
AC_TRY_COMPILE([
|
||||
#include <alsa/asoundlib.h>
|
||||
], [
|
||||
/* ensure backward compatibility */
|
||||
#if !defined(SND_LIB_MAJOR) && defined(SOUNDLIB_VERSION_MAJOR)
|
||||
#define SND_LIB_MAJOR SOUNDLIB_VERSION_MAJOR
|
||||
#endif
|
||||
#if !defined(SND_LIB_MINOR) && defined(SOUNDLIB_VERSION_MINOR)
|
||||
#define SND_LIB_MINOR SOUNDLIB_VERSION_MINOR
|
||||
#endif
|
||||
#if !defined(SND_LIB_SUBMINOR) && defined(SOUNDLIB_VERSION_SUBMINOR)
|
||||
#define SND_LIB_SUBMINOR SOUNDLIB_VERSION_SUBMINOR
|
||||
#endif
|
||||
|
||||
# if(SND_LIB_MAJOR > $alsa_min_major_version)
|
||||
exit(0);
|
||||
# else
|
||||
# if(SND_LIB_MAJOR < $alsa_min_major_version)
|
||||
# error not present
|
||||
# endif
|
||||
|
||||
# if(SND_LIB_MINOR > $alsa_min_minor_version)
|
||||
exit(0);
|
||||
# else
|
||||
# if(SND_LIB_MINOR < $alsa_min_minor_version)
|
||||
# error not present
|
||||
# endif
|
||||
|
||||
# if(SND_LIB_SUBMINOR < $alsa_min_micro_version)
|
||||
# error not present
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
exit(0);
|
||||
],
|
||||
[AC_MSG_RESULT(found.)],
|
||||
[AC_MSG_RESULT(not present.)
|
||||
ifelse([$3], , [AC_MSG_ERROR(Sufficiently new version of libasound not found.)])
|
||||
alsa_found=no]
|
||||
)
|
||||
AC_LANG_RESTORE
|
||||
|
||||
dnl Now that we know that we have the right version, let's see if we have the library and not just the headers.
|
||||
AC_CHECK_LIB([asound], [snd_ctl_open],,
|
||||
[ifelse([$3], , [AC_MSG_ERROR(No linkable libasound was found.)])
|
||||
alsa_found=no]
|
||||
)
|
||||
|
||||
if test "x$alsa_found" = "xyes" ; then
|
||||
ifelse([$2], , :, [$2])
|
||||
LIBS=`echo $LIBS | sed 's/-lasound//g'`
|
||||
LIBS=`echo $LIBS | sed 's/ //'`
|
||||
LIBS="-lasound $LIBS"
|
||||
fi
|
||||
if test "x$alsa_found" = "xno" ; then
|
||||
ifelse([$3], , :, [$3])
|
||||
CFLAGS="$alsa_save_CFLAGS"
|
||||
LDFLAGS="$alsa_save_LDFLAGS"
|
||||
LIBS="$alsa_save_LIBS"
|
||||
ALSA_CFLAGS=""
|
||||
ALSA_LIBS=""
|
||||
fi
|
||||
|
||||
dnl That should be it. Now just export out symbols:
|
||||
AC_SUBST(ALSA_CFLAGS)
|
||||
AC_SUBST(ALSA_LIBS)
|
||||
])
|
||||
|
||||
|
||||
|
||||
|
||||
AH_TOP([
|
||||
/*
|
||||
* Copyright (C) 2002 The DOSBox Team
|
||||
* Copyright (C) 2002-2003 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -180,7 +326,7 @@ AH_TOP([
|
||||
*/
|
||||
])
|
||||
|
||||
AH_TEMPLATE([C_HAS_ATTRIBUTE],[Determines if the compilers supports attributes for structures])
|
||||
AH_TEMPLATE([C_HAS_ATTRIBUTE],[Determines if the compilers supports attributes for structures.])
|
||||
|
||||
AH_BOTTOM([#define INLINE inline])
|
||||
|
||||
@ -190,5 +336,18 @@ AH_BOTTOM([#if C_HAS_ATTRIBUTE
|
||||
#define GCC_ATTRIBUTE(x) /* attribute not supported */
|
||||
#endif])
|
||||
|
||||
AH_BOTTOM([
|
||||
/* Enable some heavy debugging options */
|
||||
#define C_HEAVY_DEBUG 0
|
||||
|
||||
/* Enable some big compile-time increasing inlines */
|
||||
#define C_EXTRAINLINE 0
|
||||
|
||||
/* Enable the FPU module, still only for beta testing */
|
||||
#define C_FPU 0
|
||||
|
||||
/* Maximum memory address range in megabytes */
|
||||
#define C_MEM_MAX_SIZE 12
|
||||
])
|
||||
|
||||
|
||||
|
177
aclocal.m4
vendored
177
aclocal.m4
vendored
@ -1,4 +1,4 @@
|
||||
# aclocal.m4 generated automatically by aclocal 1.6.1 -*- Autoconf -*-
|
||||
# aclocal.m4 generated automatically by aclocal 1.6.3 -*- Autoconf -*-
|
||||
|
||||
# Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002
|
||||
# Free Software Foundation, Inc.
|
||||
@ -173,9 +173,155 @@ int main (int argc, char *argv[])
|
||||
rm -f conf.sdltest
|
||||
])
|
||||
|
||||
dnl Configure Paths for Alsa
|
||||
dnl Some modifications by Richard Boulton <richard-alsa@tartarus.org>
|
||||
dnl Christopher Lansdown <lansdoct@cs.alfred.edu>
|
||||
dnl Jaroslav Kysela <perex@suse.cz>
|
||||
dnl Last modification: alsa.m4,v 1.22 2002/05/27 11:14:20 tiwai Exp
|
||||
dnl AM_PATH_ALSA([MINIMUM-VERSION [, ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
|
||||
dnl Test for libasound, and define ALSA_CFLAGS and ALSA_LIBS as appropriate.
|
||||
dnl enables arguments --with-alsa-prefix=
|
||||
dnl --with-alsa-enc-prefix=
|
||||
dnl --disable-alsatest (this has no effect, as yet)
|
||||
dnl
|
||||
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
|
||||
AC_DEFUN(AM_PATH_ALSA,
|
||||
[dnl Save the original CFLAGS, LDFLAGS, and LIBS
|
||||
alsa_save_CFLAGS="$CFLAGS"
|
||||
alsa_save_LDFLAGS="$LDFLAGS"
|
||||
alsa_save_LIBS="$LIBS"
|
||||
alsa_found=yes
|
||||
|
||||
dnl
|
||||
dnl Get the cflags and libraries for alsa
|
||||
dnl
|
||||
AC_ARG_WITH(alsa-prefix,
|
||||
[ --with-alsa-prefix=PFX Prefix where Alsa library is installed(optional)],
|
||||
[alsa_prefix="$withval"], [alsa_prefix=""])
|
||||
|
||||
AC_ARG_WITH(alsa-inc-prefix,
|
||||
[ --with-alsa-inc-prefix=PFX Prefix where include libraries are (optional)],
|
||||
[alsa_inc_prefix="$withval"], [alsa_inc_prefix=""])
|
||||
|
||||
dnl FIXME: this is not yet implemented
|
||||
AC_ARG_ENABLE(alsatest,
|
||||
[ --disable-alsatest Do not try to compile and run a test Alsa program],
|
||||
[enable_alsatest=no],
|
||||
[enable_alsatest=yes])
|
||||
|
||||
dnl Add any special include directories
|
||||
AC_MSG_CHECKING(for ALSA CFLAGS)
|
||||
if test "$alsa_inc_prefix" != "" ; then
|
||||
ALSA_CFLAGS="$ALSA_CFLAGS -I$alsa_inc_prefix"
|
||||
CFLAGS="$CFLAGS -I$alsa_inc_prefix"
|
||||
fi
|
||||
AC_MSG_RESULT($ALSA_CFLAGS)
|
||||
|
||||
dnl add any special lib dirs
|
||||
AC_MSG_CHECKING(for ALSA LDFLAGS)
|
||||
if test "$alsa_prefix" != "" ; then
|
||||
ALSA_LIBS="$ALSA_LIBS -L$alsa_prefix"
|
||||
LDFLAGS="$LDFLAGS $ALSA_LIBS"
|
||||
fi
|
||||
|
||||
dnl add the alsa library
|
||||
ALSA_LIBS="$ALSA_LIBS -lasound -lm -ldl -lpthread"
|
||||
LIBS=`echo $LIBS | sed 's/-lm//'`
|
||||
LIBS=`echo $LIBS | sed 's/-ldl//'`
|
||||
LIBS=`echo $LIBS | sed 's/-lpthread//'`
|
||||
LIBS=`echo $LIBS | sed 's/ //'`
|
||||
LIBS="$ALSA_LIBS $LIBS"
|
||||
AC_MSG_RESULT($ALSA_LIBS)
|
||||
|
||||
dnl Check for a working version of libasound that is of the right version.
|
||||
min_alsa_version=ifelse([$1], ,0.1.1,$1)
|
||||
AC_MSG_CHECKING(for libasound headers version >= $min_alsa_version)
|
||||
no_alsa=""
|
||||
alsa_min_major_version=`echo $min_alsa_version | \
|
||||
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
|
||||
alsa_min_minor_version=`echo $min_alsa_version | \
|
||||
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
|
||||
alsa_min_micro_version=`echo $min_alsa_version | \
|
||||
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
|
||||
|
||||
AC_LANG_SAVE
|
||||
AC_LANG_C
|
||||
AC_TRY_COMPILE([
|
||||
#include <alsa/asoundlib.h>
|
||||
], [
|
||||
/* ensure backward compatibility */
|
||||
#if !defined(SND_LIB_MAJOR) && defined(SOUNDLIB_VERSION_MAJOR)
|
||||
#define SND_LIB_MAJOR SOUNDLIB_VERSION_MAJOR
|
||||
#endif
|
||||
#if !defined(SND_LIB_MINOR) && defined(SOUNDLIB_VERSION_MINOR)
|
||||
#define SND_LIB_MINOR SOUNDLIB_VERSION_MINOR
|
||||
#endif
|
||||
#if !defined(SND_LIB_SUBMINOR) && defined(SOUNDLIB_VERSION_SUBMINOR)
|
||||
#define SND_LIB_SUBMINOR SOUNDLIB_VERSION_SUBMINOR
|
||||
#endif
|
||||
|
||||
# if(SND_LIB_MAJOR > $alsa_min_major_version)
|
||||
exit(0);
|
||||
# else
|
||||
# if(SND_LIB_MAJOR < $alsa_min_major_version)
|
||||
# error not present
|
||||
# endif
|
||||
|
||||
# if(SND_LIB_MINOR > $alsa_min_minor_version)
|
||||
exit(0);
|
||||
# else
|
||||
# if(SND_LIB_MINOR < $alsa_min_minor_version)
|
||||
# error not present
|
||||
# endif
|
||||
|
||||
# if(SND_LIB_SUBMINOR < $alsa_min_micro_version)
|
||||
# error not present
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
exit(0);
|
||||
],
|
||||
[AC_MSG_RESULT(found.)],
|
||||
[AC_MSG_RESULT(not present.)
|
||||
ifelse([$3], , [AC_MSG_ERROR(Sufficiently new version of libasound not found.)])
|
||||
alsa_found=no]
|
||||
)
|
||||
AC_LANG_RESTORE
|
||||
|
||||
dnl Now that we know that we have the right version, let's see if we have the library and not just the headers.
|
||||
AC_CHECK_LIB([asound], [snd_ctl_open],,
|
||||
[ifelse([$3], , [AC_MSG_ERROR(No linkable libasound was found.)])
|
||||
alsa_found=no]
|
||||
)
|
||||
|
||||
if test "x$alsa_found" = "xyes" ; then
|
||||
ifelse([$2], , :, [$2])
|
||||
LIBS=`echo $LIBS | sed 's/-lasound//g'`
|
||||
LIBS=`echo $LIBS | sed 's/ //'`
|
||||
LIBS="-lasound $LIBS"
|
||||
fi
|
||||
if test "x$alsa_found" = "xno" ; then
|
||||
ifelse([$3], , :, [$3])
|
||||
CFLAGS="$alsa_save_CFLAGS"
|
||||
LDFLAGS="$alsa_save_LDFLAGS"
|
||||
LIBS="$alsa_save_LIBS"
|
||||
ALSA_CFLAGS=""
|
||||
ALSA_LIBS=""
|
||||
fi
|
||||
|
||||
dnl That should be it. Now just export out symbols:
|
||||
AC_SUBST(ALSA_CFLAGS)
|
||||
AC_SUBST(ALSA_LIBS)
|
||||
])
|
||||
|
||||
|
||||
|
||||
|
||||
AH_TOP([
|
||||
/*
|
||||
* Copyright (C) 2002 The DOSBox Team
|
||||
* Copyright (C) 2002-2003 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -193,7 +339,7 @@ AH_TOP([
|
||||
*/
|
||||
])
|
||||
|
||||
AH_TEMPLATE([C_HAS_ATTRIBUTE],[Determines if the compilers supports attributes for structures])
|
||||
AH_TEMPLATE([C_HAS_ATTRIBUTE],[Determines if the compilers supports attributes for structures.])
|
||||
|
||||
AH_BOTTOM([#define INLINE inline])
|
||||
|
||||
@ -203,6 +349,19 @@ AH_BOTTOM([#if C_HAS_ATTRIBUTE
|
||||
#define GCC_ATTRIBUTE(x) /* attribute not supported */
|
||||
#endif])
|
||||
|
||||
AH_BOTTOM([
|
||||
/* Enable some heavy debugging options */
|
||||
#define C_HEAVY_DEBUG 0
|
||||
|
||||
/* Enable some big compile-time increasing inlines */
|
||||
#define C_EXTRAINLINE 0
|
||||
|
||||
/* Enable the FPU module, still only for beta testing */
|
||||
#define C_FPU 0
|
||||
|
||||
/* Maximum memory address range in megabytes */
|
||||
#define C_MEM_MAX_SIZE 12
|
||||
])
|
||||
|
||||
|
||||
|
||||
@ -333,7 +492,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION],[am__api_version="1.6"])
|
||||
# Call AM_AUTOMAKE_VERSION so it can be traced.
|
||||
# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
|
||||
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
|
||||
[AM_AUTOMAKE_VERSION([1.6.1])])
|
||||
[AM_AUTOMAKE_VERSION([1.6.3])])
|
||||
|
||||
# Helper functions for option handling. -*- Autoconf -*-
|
||||
|
||||
@ -665,7 +824,7 @@ AC_REQUIRE([AM_DEP_TRACK])dnl
|
||||
|
||||
ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
|
||||
[$1], CXX, [depcc="$CXX" am_compiler_list=],
|
||||
[$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc']
|
||||
[$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
|
||||
[$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
|
||||
[depcc="$$1" am_compiler_list=])
|
||||
|
||||
@ -790,7 +949,13 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
|
||||
[for mf in $CONFIG_FILES; do
|
||||
# Strip MF so we end up with the name of the file.
|
||||
mf=`echo "$mf" | sed -e 's/:.*$//'`
|
||||
if (sed 1q $mf | fgrep 'generated by automake') > /dev/null 2>&1; then
|
||||
# Check whether this is an Automake generated Makefile or not.
|
||||
# We used to match only the files named `Makefile.in', but
|
||||
# some people rename them; so instead we look at the file content.
|
||||
# Grep'ing the first line is not enough: some people post-process
|
||||
# each Makefile.in and add a new line on top of each file to say so.
|
||||
# So let's grep whole file.
|
||||
if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
|
||||
dirpart=`AS_DIRNAME("$mf")`
|
||||
else
|
||||
continue
|
||||
|
@ -10,8 +10,4 @@ autoheader
|
||||
automake --gnits --include-deps --add-missing --copy
|
||||
autoconf
|
||||
|
||||
#Copy settings.h.cvs to settings.h and that's it,
|
||||
|
||||
directory=`dirname $0`
|
||||
cp $directory/settings.h.cvs $directory/settings.h
|
||||
echo "Now you are ready to run ./configure also check settings.h for extra build settings"
|
||||
echo "Now you are ready to run ./configure, afterwards check config.h for extra build settings"
|
||||
|
38
config.h.in
38
config.h.in
@ -2,7 +2,7 @@
|
||||
|
||||
|
||||
/*
|
||||
* Copyright (C) 2002 The DOSBox Team
|
||||
* Copyright (C) 2002-2003 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -20,14 +20,23 @@
|
||||
*/
|
||||
|
||||
|
||||
/* Determines if the compilers supports attributes for structures */
|
||||
/* Define to 1 to enable internal debugger, requires libcurses */
|
||||
#undef C_DEBUG
|
||||
|
||||
/* Determines if the compilers supports attributes for structures. */
|
||||
#undef C_HAS_ATTRIBUTE
|
||||
|
||||
/* Define to 1 to enable screenshots, requires libpng */
|
||||
#undef C_SSHOT
|
||||
|
||||
/* Define to 1 to use ALSA for MIDI */
|
||||
#undef HAVE_ALSA
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the `png' library (-lpng). */
|
||||
#undef HAVE_LIBPNG
|
||||
/* Define to 1 if you have the `asound' library (-lasound). */
|
||||
#undef HAVE_LIBASOUND
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
@ -53,6 +62,9 @@
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Compiling on Mac OS X */
|
||||
#undef MACOSX
|
||||
|
||||
/* Name of package */
|
||||
#undef PACKAGE
|
||||
|
||||
@ -80,6 +92,10 @@
|
||||
/* Version number of package */
|
||||
#undef VERSION
|
||||
|
||||
/* Define to 1 if your processor stores words with the most significant byte
|
||||
first (like Motorola and SPARC, unlike Intel and VAX). */
|
||||
#undef WORDS_BIGENDIAN
|
||||
|
||||
/* Define to empty if `const' does not conform to ANSI C. */
|
||||
#undef const
|
||||
|
||||
@ -97,3 +113,17 @@
|
||||
#else
|
||||
#define GCC_ATTRIBUTE(x) /* attribute not supported */
|
||||
#endif
|
||||
|
||||
|
||||
/* Enable some heavy debugging options */
|
||||
#define C_HEAVY_DEBUG 0
|
||||
|
||||
/* Enable some big compile-time increasing inlines */
|
||||
#define C_EXTRAINLINE 0
|
||||
|
||||
/* Enable the FPU module, still only for beta testing */
|
||||
#define C_FPU 0
|
||||
|
||||
/* Maximum memory address range in megabytes */
|
||||
#define C_MEM_MAX_SIZE 12
|
||||
|
||||
|
148
config.sub
vendored
148
config.sub
vendored
@ -1,9 +1,9 @@
|
||||
#! /bin/sh
|
||||
# Configuration validation subroutine script.
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
# 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
# 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2002-03-07'
|
||||
timestamp='2003-01-03'
|
||||
|
||||
# This file is (in principle) common to ALL GNU software.
|
||||
# The presence of a machine in this file suggests that SOME GNU software
|
||||
@ -118,7 +118,7 @@ esac
|
||||
# Here we must recognize all the valid KERNEL-OS combinations.
|
||||
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
|
||||
case $maybe_os in
|
||||
nto-qnx* | linux-gnu* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*)
|
||||
nto-qnx* | linux-gnu* | freebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
|
||||
os=-$maybe_os
|
||||
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
|
||||
;;
|
||||
@ -229,24 +229,36 @@ case $basic_machine in
|
||||
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
|
||||
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
|
||||
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
|
||||
| c4x | clipper \
|
||||
| d10v | d30v | dsp16xx \
|
||||
| fr30 \
|
||||
| clipper \
|
||||
| d10v | d30v | dlx | dsp16xx \
|
||||
| fr30 | frv \
|
||||
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
|
||||
| i370 | i860 | i960 | ia64 \
|
||||
| ip2k \
|
||||
| m32r | m68000 | m68k | m88k | mcore \
|
||||
| mips | mips16 | mips64 | mips64el | mips64orion | mips64orionel \
|
||||
| mips64vr4100 | mips64vr4100el | mips64vr4300 \
|
||||
| mips64vr4300el | mips64vr5000 | mips64vr5000el \
|
||||
| mipsbe | mipseb | mipsel | mipsle | mipstx39 | mipstx39el \
|
||||
| mipsisa32 | mipsisa64 \
|
||||
| mips | mipsbe | mipseb | mipsel | mipsle \
|
||||
| mips16 \
|
||||
| mips64 | mips64el \
|
||||
| mips64vr | mips64vrel \
|
||||
| mips64orion | mips64orionel \
|
||||
| mips64vr4100 | mips64vr4100el \
|
||||
| mips64vr4300 | mips64vr4300el \
|
||||
| mips64vr5000 | mips64vr5000el \
|
||||
| mipsisa32 | mipsisa32el \
|
||||
| mipsisa32r2 | mipsisa32r2el \
|
||||
| mipsisa64 | mipsisa64el \
|
||||
| mipsisa64sb1 | mipsisa64sb1el \
|
||||
| mipsisa64sr71k | mipsisa64sr71kel \
|
||||
| mipstx39 | mipstx39el \
|
||||
| mn10200 | mn10300 \
|
||||
| msp430 \
|
||||
| ns16k | ns32k \
|
||||
| openrisc | or32 \
|
||||
| pdp10 | pdp11 | pj | pjl \
|
||||
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
|
||||
| pyramid \
|
||||
| sh | sh[34] | sh[34]eb | shbe | shle | sh64 \
|
||||
| sh | sh[1234] | sh3e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
|
||||
| sh64 | sh64le \
|
||||
| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
|
||||
| strongarm \
|
||||
| tahoe | thumb | tic80 | tron \
|
||||
@ -281,34 +293,47 @@ case $basic_machine in
|
||||
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
|
||||
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
|
||||
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
|
||||
| arm-* | armbe-* | armle-* | armv*-* \
|
||||
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
|
||||
| avr-* \
|
||||
| bs2000-* \
|
||||
| c[123]* | c30-* | [cjt]90-* | c54x-* \
|
||||
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* \
|
||||
| clipper-* | cydra-* \
|
||||
| d10v-* | d30v-* \
|
||||
| d10v-* | d30v-* | dlx-* \
|
||||
| elxsi-* \
|
||||
| f30[01]-* | f700-* | fr30-* | fx80-* \
|
||||
| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
|
||||
| h8300-* | h8500-* \
|
||||
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
|
||||
| i*86-* | i860-* | i960-* | ia64-* \
|
||||
| ip2k-* \
|
||||
| m32r-* \
|
||||
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
|
||||
| m88110-* | m88k-* | mcore-* \
|
||||
| mips-* | mips16-* | mips64-* | mips64el-* | mips64orion-* \
|
||||
| mips64orionel-* | mips64vr4100-* | mips64vr4100el-* \
|
||||
| mips64vr4300-* | mips64vr4300el-* | mipsbe-* | mipseb-* \
|
||||
| mipsle-* | mipsel-* | mipstx39-* | mipstx39el-* \
|
||||
| none-* | np1-* | ns16k-* | ns32k-* \
|
||||
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
|
||||
| mips16-* \
|
||||
| mips64-* | mips64el-* \
|
||||
| mips64vr-* | mips64vrel-* \
|
||||
| mips64orion-* | mips64orionel-* \
|
||||
| mips64vr4100-* | mips64vr4100el-* \
|
||||
| mips64vr4300-* | mips64vr4300el-* \
|
||||
| mips64vr5000-* | mips64vr5000el-* \
|
||||
| mipsisa32-* | mipsisa32el-* \
|
||||
| mipsisa32r2-* | mipsisa32r2el-* \
|
||||
| mipsisa64-* | mipsisa64el-* \
|
||||
| mipsisa64sb1-* | mipsisa64sb1el-* \
|
||||
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
|
||||
| mipstx39-* | mipstx39el-* \
|
||||
| msp430-* \
|
||||
| none-* | np1-* | nv1-* | ns16k-* | ns32k-* \
|
||||
| orion-* \
|
||||
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
|
||||
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
|
||||
| pyramid-* \
|
||||
| romp-* | rs6000-* \
|
||||
| sh-* | sh[34]-* | sh[34]eb-* | shbe-* | shle-* | sh64-* \
|
||||
| sh-* | sh[1234]-* | sh3e-* | sh[34]eb-* | shbe-* \
|
||||
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
|
||||
| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
|
||||
| sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
|
||||
| tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \
|
||||
| tahoe-* | thumb-* | tic30-* | tic4x-* | tic54x-* | tic80-* | tron-* \
|
||||
| v850-* | v850e-* | vax-* \
|
||||
| we32k-* \
|
||||
| x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
|
||||
@ -695,6 +720,10 @@ case $basic_machine in
|
||||
np1)
|
||||
basic_machine=np1-gould
|
||||
;;
|
||||
nv1)
|
||||
basic_machine=nv1-cray
|
||||
os=-unicosmp
|
||||
;;
|
||||
nsr-tandem)
|
||||
basic_machine=nsr-tandem
|
||||
;;
|
||||
@ -728,13 +757,13 @@ case $basic_machine in
|
||||
pbb)
|
||||
basic_machine=m68k-tti
|
||||
;;
|
||||
pc532 | pc532-*)
|
||||
pc532 | pc532-*)
|
||||
basic_machine=ns32k-pc532
|
||||
;;
|
||||
pentium | p5 | k5 | k6 | nexgen | viac3)
|
||||
basic_machine=i586-pc
|
||||
;;
|
||||
pentiumpro | p6 | 6x86 | athlon)
|
||||
pentiumpro | p6 | 6x86 | athlon | athlon_*)
|
||||
basic_machine=i686-pc
|
||||
;;
|
||||
pentiumii | pentium2)
|
||||
@ -755,22 +784,22 @@ case $basic_machine in
|
||||
power) basic_machine=power-ibm
|
||||
;;
|
||||
ppc) basic_machine=powerpc-unknown
|
||||
;;
|
||||
;;
|
||||
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
ppcle | powerpclittle | ppc-le | powerpc-little)
|
||||
basic_machine=powerpcle-unknown
|
||||
;;
|
||||
;;
|
||||
ppcle-* | powerpclittle-*)
|
||||
basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
ppc64) basic_machine=powerpc64-unknown
|
||||
;;
|
||||
;;
|
||||
ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
ppc64le | powerpc64little | ppc64-le | powerpc64-little)
|
||||
basic_machine=powerpc64le-unknown
|
||||
;;
|
||||
;;
|
||||
ppc64le-* | powerpc64little-*)
|
||||
basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
@ -801,6 +830,12 @@ case $basic_machine in
|
||||
basic_machine=a29k-amd
|
||||
os=-udi
|
||||
;;
|
||||
sb1)
|
||||
basic_machine=mipsisa64sb1-unknown
|
||||
;;
|
||||
sb1el)
|
||||
basic_machine=mipsisa64sb1el-unknown
|
||||
;;
|
||||
sequent)
|
||||
basic_machine=i386-sequent
|
||||
;;
|
||||
@ -866,7 +901,7 @@ case $basic_machine in
|
||||
sun386 | sun386i | roadrunner)
|
||||
basic_machine=i386-sun
|
||||
;;
|
||||
sv1)
|
||||
sv1)
|
||||
basic_machine=sv1-cray
|
||||
os=-unicos
|
||||
;;
|
||||
@ -874,10 +909,6 @@ case $basic_machine in
|
||||
basic_machine=i386-sequent
|
||||
os=-dynix
|
||||
;;
|
||||
t3d)
|
||||
basic_machine=alpha-cray
|
||||
os=-unicos
|
||||
;;
|
||||
t3e)
|
||||
basic_machine=alphaev5-cray
|
||||
os=-unicos
|
||||
@ -886,6 +917,10 @@ case $basic_machine in
|
||||
basic_machine=t90-cray
|
||||
os=-unicos
|
||||
;;
|
||||
tic4x | c4x*)
|
||||
basic_machine=tic4x-unknown
|
||||
os=-coff
|
||||
;;
|
||||
tic54x | c54x*)
|
||||
basic_machine=tic54x-unknown
|
||||
os=-coff
|
||||
@ -924,8 +959,8 @@ case $basic_machine in
|
||||
os=-vms
|
||||
;;
|
||||
vpp*|vx|vx-*)
|
||||
basic_machine=f301-fujitsu
|
||||
;;
|
||||
basic_machine=f301-fujitsu
|
||||
;;
|
||||
vxworks960)
|
||||
basic_machine=i960-wrs
|
||||
os=-vxworks
|
||||
@ -946,11 +981,7 @@ case $basic_machine in
|
||||
basic_machine=hppa1.1-winbond
|
||||
os=-proelf
|
||||
;;
|
||||
windows32)
|
||||
basic_machine=i386-pc
|
||||
os=-windows32-msvcrt
|
||||
;;
|
||||
xps | xps100)
|
||||
xps | xps100)
|
||||
basic_machine=xps100-honeywell
|
||||
;;
|
||||
ymp)
|
||||
@ -996,7 +1027,7 @@ case $basic_machine in
|
||||
we32k)
|
||||
basic_machine=we32k-att
|
||||
;;
|
||||
sh3 | sh4 | sh3eb | sh4eb)
|
||||
sh3 | sh4 | sh3eb | sh4eb | sh[1234]le | sh3ele)
|
||||
basic_machine=sh-unknown
|
||||
;;
|
||||
sh64)
|
||||
@ -1005,7 +1036,7 @@ case $basic_machine in
|
||||
sparc | sparcv9 | sparcv9b)
|
||||
basic_machine=sparc-sun
|
||||
;;
|
||||
cydra)
|
||||
cydra)
|
||||
basic_machine=cydra-cydrome
|
||||
;;
|
||||
orion)
|
||||
@ -1020,10 +1051,6 @@ case $basic_machine in
|
||||
pmac | pmac-mpw)
|
||||
basic_machine=powerpc-apple
|
||||
;;
|
||||
c4x*)
|
||||
basic_machine=c4x-none
|
||||
os=-coff
|
||||
;;
|
||||
*-unknown)
|
||||
# Make sure to match an already-canonicalized machine name.
|
||||
;;
|
||||
@ -1086,11 +1113,12 @@ case $os in
|
||||
| -chorusos* | -chorusrdb* \
|
||||
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
|
||||
| -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
|
||||
| -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
|
||||
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
|
||||
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
|
||||
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
|
||||
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
|
||||
| -morphos* | -superux* | -rtmk* | -rtmk-nova*)
|
||||
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
|
||||
| -powermax* | -dnix* | -microbsd*)
|
||||
# Remember, each alternative MUST END IN *, to match a version number.
|
||||
;;
|
||||
-qnx*)
|
||||
@ -1102,8 +1130,10 @@ case $os in
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
-nto-qnx*)
|
||||
;;
|
||||
-nto*)
|
||||
os=-nto-qnx
|
||||
os=`echo $os | sed -e 's|nto|nto-qnx|'`
|
||||
;;
|
||||
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
|
||||
| -windows* | -osx | -abug | -netware* | -os9* | -beos* \
|
||||
@ -1155,7 +1185,7 @@ case $os in
|
||||
os=-rtmk-nova
|
||||
;;
|
||||
-ns2 )
|
||||
os=-nextstep2
|
||||
os=-nextstep2
|
||||
;;
|
||||
-nsk*)
|
||||
os=-nsk
|
||||
@ -1194,8 +1224,8 @@ case $os in
|
||||
-xenix)
|
||||
os=-xenix
|
||||
;;
|
||||
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
|
||||
os=-mint
|
||||
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
|
||||
os=-mint
|
||||
;;
|
||||
-none)
|
||||
;;
|
||||
@ -1232,7 +1262,7 @@ case $basic_machine in
|
||||
pdp10-*)
|
||||
os=-tops20
|
||||
;;
|
||||
pdp11-*)
|
||||
pdp11-*)
|
||||
os=-none
|
||||
;;
|
||||
*-dec | vax-*)
|
||||
@ -1325,19 +1355,19 @@ case $basic_machine in
|
||||
*-next)
|
||||
os=-nextstep3
|
||||
;;
|
||||
*-gould)
|
||||
*-gould)
|
||||
os=-sysv
|
||||
;;
|
||||
*-highlevel)
|
||||
*-highlevel)
|
||||
os=-bsd
|
||||
;;
|
||||
*-encore)
|
||||
os=-bsd
|
||||
;;
|
||||
*-sgi)
|
||||
*-sgi)
|
||||
os=-irix
|
||||
;;
|
||||
*-siemens)
|
||||
*-siemens)
|
||||
os=-sysv4
|
||||
;;
|
||||
*-masscomp)
|
||||
@ -1409,7 +1439,7 @@ case $basic_machine in
|
||||
-ptx*)
|
||||
vendor=sequent
|
||||
;;
|
||||
-vxsim* | -vxworks*)
|
||||
-vxsim* | -vxworks* | -windiss*)
|
||||
vendor=wrs
|
||||
;;
|
||||
-aux*)
|
||||
|
51
configure.in
51
configure.in
@ -1,5 +1,6 @@
|
||||
dnl Init.
|
||||
AC_INIT(dosbox,0.57)
|
||||
AC_INIT(dosbox,0.58)
|
||||
AC_PREREQ(2.50)
|
||||
AC_CONFIG_SRCDIR(README)
|
||||
|
||||
dnl Detect the canonical host and target build environment
|
||||
@ -36,13 +37,58 @@ AC_TYPE_SIZE_T
|
||||
AC_STRUCT_TM
|
||||
|
||||
dnl Checks for libraries.
|
||||
AC_CHECK_LIB(png, png_check_sig, , AC_MSG_ERROR([*** libpng not found!]), -lz)
|
||||
|
||||
#Check if the compiler support attributes
|
||||
AC_MSG_CHECKING(if compiler allows __attribute__)
|
||||
AC_TRY_COMPILE([], [typedef struct { } __attribute__ ((packed)) junk;],
|
||||
[ AC_MSG_RESULT(yes);AC_DEFINE(C_HAS_ATTRIBUTE)],AC_MSG_RESULT(no))
|
||||
|
||||
AM_PATH_ALSA(0.9.0, AC_DEFINE(HAVE_ALSA,1,[Define to 1 to use ALSA for MIDI]) , : )
|
||||
|
||||
#Check for big endian machine, should #define WORD_BIGENDIAN if so
|
||||
AC_C_BIGENDIAN
|
||||
|
||||
#Features to enable/disable
|
||||
AH_TEMPLATE(C_DEBUG,[Define to 1 to enable internal debugger, requires libcurses])
|
||||
AC_ARG_ENABLE(debug,[ --enable-debug Enable debug mode],[
|
||||
AC_CHECK_HEADER(curses.h,have_curses_h=yes,)
|
||||
AC_CHECK_LIB(curses, initscr, have_curses_lib=yes, , )
|
||||
|
||||
if test x$have_curses_lib = xyes -a x$have_curses_h = xyes ; then
|
||||
LIBS="$LIBS -lcurses"
|
||||
AC_DEFINE(C_DEBUG,1)
|
||||
else
|
||||
AC_MSG_WARN([Can't enable debug mode without libcurses])
|
||||
fi
|
||||
],)
|
||||
|
||||
AH_TEMPLATE(C_SSHOT,[Define to 1 to enable screenshots, requires libpng])
|
||||
AC_ARG_ENABLE(shots,[ --enable-shots Enable screenshot support],[
|
||||
AC_CHECK_HEADER(png.h,have_png_h=yes,)
|
||||
AC_CHECK_LIB(png, png_check_sig, have_png_lib=yes, ,-lz)
|
||||
if test x$have_png_lib = xyes -a x$have_png_h = xyes ; then
|
||||
LIBS="$LIBS -lpng -lz"
|
||||
AC_DEFINE(C_SSHOT,1)
|
||||
else
|
||||
AC_MSG_WARN([Can't enable screenshots without libpng])
|
||||
fi
|
||||
],)
|
||||
|
||||
dnl Some host detection and actions for them
|
||||
case "$target" in
|
||||
*-*-cygwin* | *-*-mingw32*)
|
||||
LIBS="$LIBS -lwinmm"
|
||||
;;
|
||||
*-*-darwin*)
|
||||
dnl We have a problem here: both MacOS X and Darwin report
|
||||
dnl the same signature "powerpc-apple-darwin*" - so we have
|
||||
dnl to do more to distinguish them.
|
||||
dnl For now I am lazy and do not add proper detection code.
|
||||
AC_DEFINE(MACOSX, 1, [Compiling on Mac OS X])
|
||||
LIBS="$LIBS -framework AudioUnit"
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
AC_OUTPUT([
|
||||
Makefile
|
||||
@ -61,4 +107,5 @@ src/platform/Makefile
|
||||
src/platform/visualc/Makefile
|
||||
visualc/Makefile
|
||||
include/Makefile
|
||||
docs/Makefile
|
||||
])
|
||||
|
215
depcomp
215
depcomp
@ -209,16 +209,20 @@ aix)
|
||||
tru64)
|
||||
# The Tru64 compiler uses -MD to generate dependencies as a side
|
||||
# effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
|
||||
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
|
||||
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
|
||||
# dependencies in `foo.d' instead, so we check for that too.
|
||||
# Subdirectories are respected.
|
||||
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
|
||||
test "x$dir" = "x$object" && dir=
|
||||
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
|
||||
|
||||
base=`echo "$object" | sed -e 's/\.o$//' -e 's/\.lo$//'`
|
||||
tmpdepfile1="$base.o.d"
|
||||
tmpdepfile2="$base.d"
|
||||
if test "$libtool" = yes; then
|
||||
tmpdepfile1="$dir.libs/$base.lo.d"
|
||||
tmpdepfile2="$dir.libs/$base.d"
|
||||
"$@" -Wc,-MD
|
||||
else
|
||||
tmpdepfile1="$dir$base.o.d"
|
||||
tmpdepfile2="$dir$base.d"
|
||||
"$@" -MD
|
||||
fi
|
||||
|
||||
@ -250,34 +254,40 @@ tru64)
|
||||
|
||||
dashmstdout)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the proprocessed file to stdout, regardless of -o,
|
||||
# because we must use -o when running libtool.
|
||||
test -z "$dashmflag" && dashmflag=-M
|
||||
( IFS=" "
|
||||
case " $* " in
|
||||
*" --mode=compile "*) # this is libtool, let us make it quiet
|
||||
for arg
|
||||
do # cycle over the arguments
|
||||
case "$arg" in
|
||||
"--mode=compile")
|
||||
# insert --quiet before "--mode=compile"
|
||||
set fnord "$@" --quiet
|
||||
shift # fnord
|
||||
;;
|
||||
esac
|
||||
set fnord "$@" "$arg"
|
||||
shift # fnord
|
||||
shift # "$arg"
|
||||
done
|
||||
# always write the proprocessed file to stdout, regardless of -o.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test $1 != '--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
# Remove `-o $object'. We will use -o /dev/null later,
|
||||
# however we can't do the remplacement now because
|
||||
# `-o $object' might simply not be used
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
;;
|
||||
esac
|
||||
"$@" $dashmflag | sed 's:^[^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
|
||||
) &
|
||||
proc=$!
|
||||
"$@"
|
||||
stat=$?
|
||||
wait "$proc"
|
||||
if test "$stat" != 0; then exit $stat; fi
|
||||
done
|
||||
|
||||
test -z "$dashmflag" && dashmflag=-M
|
||||
"$@" -o /dev/null $dashmflag | sed 's:^[^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
cat < "$tmpdepfile" > "$depfile"
|
||||
tr ' ' '
|
||||
@ -295,33 +305,28 @@ dashXmstdout)
|
||||
;;
|
||||
|
||||
makedepend)
|
||||
"$@" || exit $?
|
||||
# X makedepend
|
||||
(
|
||||
shift
|
||||
cleared=no
|
||||
for arg in "$@"; do
|
||||
case $cleared in no)
|
||||
set ""; shift
|
||||
cleared=yes
|
||||
esac
|
||||
case "$arg" in
|
||||
-D*|-I*)
|
||||
set fnord "$@" "$arg"; shift;;
|
||||
-*)
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"; shift;;
|
||||
esac
|
||||
done
|
||||
obj_suffix="`echo $object | sed 's/^.*\././'`"
|
||||
touch "$tmpdepfile"
|
||||
${MAKEDEPEND-makedepend} 2>/dev/null -o"$obj_suffix" -f"$tmpdepfile" "$@"
|
||||
) &
|
||||
proc=$!
|
||||
"$@"
|
||||
stat=$?
|
||||
wait "$proc"
|
||||
if test "$stat" != 0; then exit $stat; fi
|
||||
shift
|
||||
cleared=no
|
||||
for arg in "$@"; do
|
||||
case $cleared in
|
||||
no)
|
||||
set ""; shift
|
||||
cleared=yes ;;
|
||||
esac
|
||||
case "$arg" in
|
||||
-D*|-I*)
|
||||
set fnord "$@" "$arg"; shift ;;
|
||||
-*)
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"; shift ;;
|
||||
esac
|
||||
done
|
||||
obj_suffix="`echo $object | sed 's/^.*\././'`"
|
||||
touch "$tmpdepfile"
|
||||
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
|
||||
rm -f "$depfile"
|
||||
cat < "$tmpdepfile" > "$depfile"
|
||||
sed '1,2d' "$tmpdepfile" | tr ' ' '
|
||||
@ -334,35 +339,39 @@ makedepend)
|
||||
|
||||
cpp)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the proprocessed file to stdout, regardless of -o,
|
||||
# because we must use -o when running libtool.
|
||||
( IFS=" "
|
||||
case " $* " in
|
||||
*" --mode=compile "*)
|
||||
for arg
|
||||
do # cycle over the arguments
|
||||
case $arg in
|
||||
"--mode=compile")
|
||||
# insert --quiet before "--mode=compile"
|
||||
set fnord "$@" --quiet
|
||||
shift # fnord
|
||||
;;
|
||||
esac
|
||||
set fnord "$@" "$arg"
|
||||
shift # fnord
|
||||
shift # "$arg"
|
||||
done
|
||||
# always write the proprocessed file to stdout.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test $1 != '--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
# Remove `-o $object'.
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
;;
|
||||
esac
|
||||
"$@" -E |
|
||||
done
|
||||
|
||||
"$@" -E |
|
||||
sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
|
||||
sed '$ s: \\$::' > "$tmpdepfile"
|
||||
) &
|
||||
proc=$!
|
||||
"$@"
|
||||
stat=$?
|
||||
wait "$proc"
|
||||
if test "$stat" != 0; then exit $stat; fi
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
cat < "$tmpdepfile" >> "$depfile"
|
||||
@ -374,47 +383,25 @@ msvisualcpp)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the proprocessed file to stdout, regardless of -o,
|
||||
# because we must use -o when running libtool.
|
||||
( IFS=" "
|
||||
case " $* " in
|
||||
*" --mode=compile "*)
|
||||
for arg
|
||||
do # cycle over the arguments
|
||||
case $arg in
|
||||
"--mode=compile")
|
||||
# insert --quiet before "--mode=compile"
|
||||
set fnord "$@" --quiet
|
||||
shift # fnord
|
||||
;;
|
||||
esac
|
||||
set fnord "$@" "$arg"
|
||||
shift # fnord
|
||||
shift # "$arg"
|
||||
done
|
||||
;;
|
||||
esac
|
||||
for arg
|
||||
do
|
||||
case "$arg" in
|
||||
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
|
||||
"$@" || exit $?
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case "$arg" in
|
||||
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
|
||||
set fnord "$@"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
"$@" -E |
|
||||
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
|
||||
) &
|
||||
proc=$!
|
||||
"$@"
|
||||
stat=$?
|
||||
wait "$proc"
|
||||
if test "$stat" != 0; then exit $stat; fi
|
||||
esac
|
||||
done
|
||||
"$@" -E |
|
||||
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
|
||||
|
8
docs/Makefile.am
Normal file
8
docs/Makefile.am
Normal file
@ -0,0 +1,8 @@
|
||||
# Main Makefile for DOSBox
|
||||
|
||||
man_MANS = dosbox.1
|
||||
EXTRA_DIST = $(man_MANS)
|
||||
|
||||
|
||||
|
||||
|
262
docs/Makefile.in
Normal file
262
docs/Makefile.in
Normal file
@ -0,0 +1,262 @@
|
||||
# Makefile.in generated by automake 1.6.3 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
|
||||
# Free Software Foundation, Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
# Main Makefile for DOSBox
|
||||
SHELL = @SHELL@
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
VPATH = @srcdir@
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
bindir = @bindir@
|
||||
sbindir = @sbindir@
|
||||
libexecdir = @libexecdir@
|
||||
datadir = @datadir@
|
||||
sysconfdir = @sysconfdir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
localstatedir = @localstatedir@
|
||||
libdir = @libdir@
|
||||
infodir = @infodir@
|
||||
mandir = @mandir@
|
||||
includedir = @includedir@
|
||||
oldincludedir = /usr/include
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
top_builddir = ..
|
||||
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = @program_transform_name@
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
host_alias = @host_alias@
|
||||
host_triplet = @host@
|
||||
|
||||
EXEEXT = @EXEEXT@
|
||||
OBJEXT = @OBJEXT@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
ALSA_CFLAGS = @ALSA_CFLAGS@
|
||||
ALSA_LIBS = @ALSA_LIBS@
|
||||
AMTAR = @AMTAR@
|
||||
AWK = @AWK@
|
||||
CC = @CC@
|
||||
CPP = @CPP@
|
||||
CXX = @CXX@
|
||||
DEPDIR = @DEPDIR@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
PACKAGE = @PACKAGE@
|
||||
RANLIB = @RANLIB@
|
||||
SDL_CFLAGS = @SDL_CFLAGS@
|
||||
SDL_CONFIG = @SDL_CONFIG@
|
||||
SDL_LIBS = @SDL_LIBS@
|
||||
STRIP = @STRIP@
|
||||
VERSION = @VERSION@
|
||||
am__include = @am__include@
|
||||
am__quote = @am__quote@
|
||||
install_sh = @install_sh@
|
||||
|
||||
man_MANS = dosbox.1
|
||||
EXTRA_DIST = $(man_MANS)
|
||||
subdir = docs
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
CONFIG_HEADER = $(top_builddir)/config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
DIST_SOURCES =
|
||||
|
||||
NROFF = nroff
|
||||
MANS = $(man_MANS)
|
||||
DIST_COMMON = Makefile.am Makefile.in
|
||||
all: all-am
|
||||
|
||||
.SUFFIXES:
|
||||
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
|
||||
cd $(top_srcdir) && \
|
||||
$(AUTOMAKE) --gnits docs/Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
|
||||
uninstall-info-am:
|
||||
|
||||
man1dir = $(mandir)/man1
|
||||
install-man1: $(man1_MANS) $(man_MANS)
|
||||
@$(NORMAL_INSTALL)
|
||||
$(mkinstalldirs) $(DESTDIR)$(man1dir)
|
||||
@list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \
|
||||
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
|
||||
for i in $$l2; do \
|
||||
case "$$i" in \
|
||||
*.1*) list="$$list $$i" ;; \
|
||||
esac; \
|
||||
done; \
|
||||
for i in $$list; do \
|
||||
if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
|
||||
else file=$$i; fi; \
|
||||
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
|
||||
case "$$ext" in \
|
||||
1*) ;; \
|
||||
*) ext='1' ;; \
|
||||
esac; \
|
||||
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
|
||||
inst=`echo $$inst | sed -e 's/^.*\///'`; \
|
||||
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
|
||||
echo " $(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst"; \
|
||||
$(INSTALL_DATA) $$file $(DESTDIR)$(man1dir)/$$inst; \
|
||||
done
|
||||
uninstall-man1:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \
|
||||
l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
|
||||
for i in $$l2; do \
|
||||
case "$$i" in \
|
||||
*.1*) list="$$list $$i" ;; \
|
||||
esac; \
|
||||
done; \
|
||||
for i in $$list; do \
|
||||
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
|
||||
inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
|
||||
inst=`echo $$inst | sed -e 's/^.*\///'`; \
|
||||
inst=`echo $$inst | sed '$(transform)'`.$$ext; \
|
||||
echo " rm -f $(DESTDIR)$(man1dir)/$$inst"; \
|
||||
rm -f $(DESTDIR)$(man1dir)/$$inst; \
|
||||
done
|
||||
tags: TAGS
|
||||
TAGS:
|
||||
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
|
||||
top_distdir = ..
|
||||
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@list='$(DISTFILES)'; for file in $$list; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
|
||||
dir="/$$dir"; \
|
||||
$(mkinstalldirs) "$(distdir)$$dir"; \
|
||||
else \
|
||||
dir=''; \
|
||||
fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
|
||||
fi; \
|
||||
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
|
||||
else \
|
||||
test -f $(distdir)/$$file \
|
||||
|| cp -p $$d/$$file $(distdir)/$$file \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
all-am: Makefile $(MANS)
|
||||
|
||||
installdirs:
|
||||
$(mkinstalldirs) $(DESTDIR)$(man1dir)
|
||||
|
||||
install: install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
INSTALL_STRIP_FLAG=-s \
|
||||
`test -z '$(STRIP)' || \
|
||||
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-rm -f Makefile $(CONFIG_CLEAN_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-generic mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
|
||||
distclean-am: clean-am distclean-generic
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
dvi-am:
|
||||
|
||||
info: info-am
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am: install-man
|
||||
|
||||
install-exec-am:
|
||||
|
||||
install-info: install-info-am
|
||||
|
||||
install-man: install-man1
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-generic
|
||||
|
||||
uninstall-am: uninstall-info-am uninstall-man
|
||||
|
||||
uninstall-man: uninstall-man1
|
||||
|
||||
.PHONY: all all-am check check-am clean clean-generic distclean \
|
||||
distclean-generic distdir dvi dvi-am info info-am install \
|
||||
install-am install-data install-data-am install-exec \
|
||||
install-exec-am install-info install-info-am install-man \
|
||||
install-man1 install-strip installcheck installcheck-am \
|
||||
installdirs maintainer-clean maintainer-clean-generic \
|
||||
mostlyclean mostlyclean-generic uninstall uninstall-am \
|
||||
uninstall-info-am uninstall-man uninstall-man1
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
60
docs/dosbox.1
Normal file
60
docs/dosbox.1
Normal file
@ -0,0 +1,60 @@
|
||||
.\" Hey, EMACS: -*- nroff -*-
|
||||
.TH DOSBOX 1 "March 31, 2003"
|
||||
.\" Please adjust this date whenever revising the manpage.
|
||||
.SH NAME
|
||||
dosbox \- an x86/DOS emulator with sound/graphics primarily for games
|
||||
.SH SYNOPSIS
|
||||
.B dosbox
|
||||
[\fB-fullscreen\fR]
|
||||
[\fB-conf\fR \fIconfigfile\fR]
|
||||
[\fB-lang\fR \fIlangfile\fR]
|
||||
[\fBfile\fR]
|
||||
[\fB-c\fR \fIcommand1\fR <\fIcommand2\fR>...]
|
||||
.br
|
||||
.SH DESCRIPTION
|
||||
This manual page briefly documents
|
||||
\fBdosbox\fR, an x86/DOS emulator capable of running many games.
|
||||
.TP
|
||||
The optional \fBfile\fR argument should be a DOS executable or a directory. If it is a dos executable (.com .exe .bat) the program will run automatically. If it is a directory, a DOS session will run with the directory mounted as C:.
|
||||
.SH OPTIONS
|
||||
A summary of options is included below.
|
||||
.TP
|
||||
\fB-fullscreen\fR
|
||||
Start DOSBox in fullscreen mode
|
||||
.TP
|
||||
\fB-c\fR \fIcommand 1\fR [\fIcommand 2\fR] ...
|
||||
Run one or more DOS commands after starting \fBdosbox\fR. If an executable is
|
||||
also specified, these commands will be executed before running the program.
|
||||
.TP
|
||||
\fB-conf\fR \fIconfigfile\fR
|
||||
Start \fBdosbox\fR with the options specified in \fIconfigfile\fR
|
||||
.TP
|
||||
\fB-lang\fR \fIlangfile\fR
|
||||
Start \fBdosbox\fR with the language specified in \fIlangfile\fR
|
||||
.SH INTERNAL COMMANDS
|
||||
.B dosbox
|
||||
supports most of the DOS commands found in command.com. In addition, the
|
||||
following extra commands are available:
|
||||
.TP
|
||||
\fBMOUNT\fR [\fB-t\fR \fItype\fR] [\fB-size\fR \fIsize\fR] \fBdriveletter\fR \fBsourcedirectory\fR [\fB-aspi\fR]
|
||||
Map \fBsourcedirectory\fR to \fBdriveletter\fR.
|
||||
\fItype\fR may be \fIdir\fR for a hard drive, \fIfloppy\fR for a floppy
|
||||
drive or \fIcdrom\fR for a cdrom. \fIsize\fR specifies the size of the volume.
|
||||
You can force ASPI mode for a cdrom with \fB-aspi\fR.
|
||||
.TP
|
||||
\fBMEM\fR
|
||||
Display the amount of free memory
|
||||
.TP
|
||||
\fBCONFIG\fR [\fB-writeconf\fR] [\fB-writelang\fR] \fBfile\fR
|
||||
Write the current configuration or language settings to \fBfile\fR
|
||||
.SH FILES
|
||||
Configuration and language files use a format similar to Windows .ini files. If a file named
|
||||
\fBdosbox.conf\fR is found in the current directory, it will be automatically loaded.
|
||||
.SH BUGS
|
||||
Not all DOS programs work properly. Notably, any program that uses protected mode will not work at all.
|
||||
DOSBox will exit without warning if an error occured.
|
||||
.SH SEE ALSO
|
||||
The README in /usr/share/doc/dosbox
|
||||
.SH AUTHOR
|
||||
This manual page was written by Peter Veenstra <H.P.Veenstra@student.rug.nl> and James Oakley <jfunk@funktronics.ca>,
|
||||
for the Debian system (but may be used by others).
|
@ -1,4 +1,4 @@
|
||||
# Makefile.in generated by automake 1.6.1 from Makefile.am.
|
||||
# Makefile.in generated by automake 1.6.3 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
|
||||
@ -49,6 +49,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = @program_transform_name@
|
||||
@ -64,6 +65,8 @@ host_triplet = @host@
|
||||
EXEEXT = @EXEEXT@
|
||||
OBJEXT = @OBJEXT@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
ALSA_CFLAGS = @ALSA_CFLAGS@
|
||||
ALSA_LIBS = @ALSA_LIBS@
|
||||
AMTAR = @AMTAR@
|
||||
AWK = @AWK@
|
||||
CC = @CC@
|
||||
@ -169,7 +172,7 @@ top_distdir = ..
|
||||
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@for file in $(DISTFILES); do \
|
||||
@list='$(DISTFILES)'; for file in $$list; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
|
||||
@ -214,7 +217,7 @@ mostlyclean-generic:
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]*
|
||||
-rm -f Makefile $(CONFIG_CLEAN_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
|
@ -50,7 +50,5 @@
|
||||
#define ftruncate(blah,blah2) chsize(blah,blah2)
|
||||
#endif
|
||||
|
||||
extern const char * dosbox_datadir;
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -16,10 +16,14 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
typedef void (* DMA_EnableCallBack)(bool enable);
|
||||
|
||||
Bit16u DMA_8_Read(Bit32u channel,Bit8u * buffer,Bit16u count);
|
||||
Bit16u DMA_8_Write(Bit32u dmachan,Bit8u * buffer,Bit16u count);
|
||||
|
||||
Bit16u DMA_16_Read(Bit32u channel,Bit8u * buffer,Bit16u count);
|
||||
Bit16u DMA_16_Write(Bit32u dmachan,Bit8u * buffer,Bit16u count);
|
||||
void DMA_SetEnableCallBack(Bitu channel,DMA_EnableCallBack callback);
|
||||
|
||||
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);
|
||||
|
||||
|
@ -29,14 +29,6 @@ struct CommandTail{
|
||||
} GCC_ATTRIBUTE(packed);
|
||||
|
||||
|
||||
struct MCB {
|
||||
Bit8u type;
|
||||
Bit16u psp_segment;
|
||||
Bit16u size;
|
||||
Bit8u unused[3];
|
||||
Bit8u filename[8];
|
||||
} GCC_ATTRIBUTE(packed);
|
||||
|
||||
#pragma pack ()
|
||||
|
||||
struct DOS_Date {
|
||||
@ -267,7 +259,9 @@ public:
|
||||
void SetFCB1 (RealPt src);
|
||||
void SetFCB2 (RealPt src);
|
||||
void SetCommandTail (RealPt src);
|
||||
|
||||
bool SetNumFiles (Bit16u fileNum);
|
||||
Bit16u FindEntryByHandle (Bit8u handle);
|
||||
|
||||
private:
|
||||
#pragma pack(1)
|
||||
struct sPSP {
|
||||
@ -362,6 +356,9 @@ public:
|
||||
Bit8u GetSearchDrive(void);
|
||||
void GetSearchParams(Bit8u & _sattr,char * _spattern);
|
||||
void GetResult(char * _name,Bit32u & _size,Bit16u & _date,Bit16u & _time,Bit8u & _attr);
|
||||
|
||||
void SetDirID(Bit16u entry) { sSave(sDTA,dirID,entry); };
|
||||
Bit16u GetDirID(void) { return sGet(sDTA,dirID); };
|
||||
private:
|
||||
#pragma pack(1)
|
||||
struct sDTA {
|
||||
@ -369,7 +366,8 @@ private:
|
||||
Bit8u sattr; /* The Attributes that need to be found */
|
||||
Bit8u sname[8]; /* The Search pattern for the filename */
|
||||
Bit8u sext[3]; /* The Search pattern for the extenstion */
|
||||
Bit8u fill[8];
|
||||
Bit16u dirID; /* custom: dir-search ID for multiple searches at the same time */
|
||||
Bit8u fill[6];
|
||||
Bit8u attr;
|
||||
Bit16u time;
|
||||
Bit16u date;
|
||||
@ -419,10 +417,32 @@ private:
|
||||
#pragma pack ()
|
||||
};
|
||||
|
||||
class DOS_MCB : public MemStruct{
|
||||
public:
|
||||
DOS_MCB(Bit16u seg) { SetPt(seg); }
|
||||
void SetFileName(char * _name) { MEM_BlockWrite(pt+offsetof(sMCB,filename),_name,8); }
|
||||
void GetFileName(char * _name) { MEM_BlockRead(pt+offsetof(sMCB,filename),_name,8);_name[8]=0;}
|
||||
void SetType(Bit8u _type) { sSave(sMCB,type,_type);}
|
||||
void SetSize(Bit16u _size) { sSave(sMCB,size,_size);}
|
||||
void SetPSPSeg(Bit16u _pspseg) { sSave(sMCB,psp_segment,_pspseg);}
|
||||
Bit8u GetType(void) { return sGet(sMCB,type);}
|
||||
Bit16u GetSize(void) { return sGet(sMCB,size);}
|
||||
Bit16u GetPSPSeg(void) { return sGet(sMCB,psp_segment);}
|
||||
private:
|
||||
#pragma pack (1)
|
||||
struct sMCB {
|
||||
Bit8u type;
|
||||
Bit16u psp_segment;
|
||||
Bit16u size;
|
||||
Bit8u unused[3];
|
||||
Bit8u filename[8];
|
||||
} GCC_ATTRIBUTE(packed);
|
||||
#pragma pack ()
|
||||
};
|
||||
|
||||
extern DOS_InfoBlock dos_infoblock;;
|
||||
|
||||
INLINE Bit8u RealHandle(Bit16u handle) {
|
||||
|
||||
DOS_PSP psp(dos.psp);
|
||||
return psp.GetFileHandle(handle);
|
||||
}
|
||||
|
@ -19,7 +19,10 @@
|
||||
#ifndef DOSSYSTEM_H_
|
||||
#define DOSSYSTEM_H_
|
||||
|
||||
#include <string.h>
|
||||
#include <vector>
|
||||
#include "dosbox.h"
|
||||
#include "cross.h"
|
||||
|
||||
#define DOS_NAMELENGTH 12
|
||||
#define DOS_NAMELENGTH_ASCII (DOS_NAMELENGTH+1)
|
||||
@ -48,18 +51,25 @@ class DOS_DTA;
|
||||
|
||||
class DOS_File {
|
||||
public:
|
||||
virtual ~DOS_File(){};
|
||||
virtual bool Read(Bit8u * data,Bit16u * size)=0;
|
||||
virtual bool Write(Bit8u * data,Bit16u * size)=0;
|
||||
virtual bool Seek(Bit32u * pos,Bit32u type)=0;
|
||||
virtual bool Close()=0;
|
||||
virtual Bit16u GetInformation(void)=0;
|
||||
DOS_File() { name=0; };
|
||||
virtual ~DOS_File(){};
|
||||
virtual bool Read(Bit8u * data,Bit16u * size)=0;
|
||||
virtual bool Write(Bit8u * data,Bit16u * size)=0;
|
||||
virtual bool Seek(Bit32u * pos,Bit32u type)=0;
|
||||
virtual bool Close()=0;
|
||||
virtual Bit16u GetInformation(void)=0;
|
||||
virtual void SetName(const char* _name) { if (name) delete[] name; name = new char[strlen(_name)+1]; strcpy(name,_name); }
|
||||
virtual char* GetName(void) { return name; };
|
||||
virtual bool IsOpen() { return open; };
|
||||
virtual bool IsName(const char* _name) { if (!name) return false; return strcmp(name,_name)==0; };
|
||||
Bit8u type;
|
||||
Bit32u flags;
|
||||
Bit16u time;
|
||||
Bit16u date;
|
||||
Bit16u attr;
|
||||
Bit32u size;
|
||||
bool open;
|
||||
char* name;
|
||||
/* Some Device Specific Stuff */
|
||||
};
|
||||
|
||||
@ -70,6 +80,114 @@ public:
|
||||
Bit8u fhandle;
|
||||
};
|
||||
|
||||
#define MAX_OPENDIRS 16
|
||||
|
||||
class DOS_Drive_Cache {
|
||||
public:
|
||||
DOS_Drive_Cache (void);
|
||||
DOS_Drive_Cache (const char* path);
|
||||
~DOS_Drive_Cache (void);
|
||||
|
||||
typedef enum TDirSort { NOSORT, ALPHABETICAL, DIRALPHABETICAL, ALPHABETICALREV, DIRALPHABETICALREV };
|
||||
|
||||
void SetBaseDir (const char* path);
|
||||
void SetDirSort (TDirSort sort) { sortDirType = sort; };
|
||||
bool OpenDir (const char* path, Bit16u& id);
|
||||
bool ReadDir (Bit16u id, char* &result);
|
||||
|
||||
void ExpandName (char* path);
|
||||
char* GetExpandName (const char* path);
|
||||
bool GetShortName (const char* fullname, char* shortname);
|
||||
|
||||
void CacheOut (const char* path, bool ignoreLastDir = false);
|
||||
void AddEntry (const char* path, bool checkExist = false);
|
||||
void DeleteEntry (const char* path, bool ignoreLastDir = false);
|
||||
|
||||
void EmptyCache (void);
|
||||
|
||||
class CFileInfo {
|
||||
public:
|
||||
~CFileInfo(void) {
|
||||
for (Bit32u i=0; i<fileList.size(); i++) delete fileList[i];
|
||||
fileList.clear();
|
||||
longNameList.clear();
|
||||
outputList.clear();
|
||||
};
|
||||
char orgname [CROSS_LEN];
|
||||
char shortname [DOS_NAMELENGTH_ASCII];
|
||||
bool isDir;
|
||||
Bitu nextEntry;
|
||||
Bitu shortNr;
|
||||
Bitu compareCount;
|
||||
// contents
|
||||
std::vector<CFileInfo*> fileList;
|
||||
std::vector<CFileInfo*> longNameList;
|
||||
std::vector<CFileInfo*> outputList;
|
||||
};
|
||||
|
||||
private:
|
||||
|
||||
bool RemoveTrailingDot (char* shortname);
|
||||
Bit16s GetLongName (CFileInfo* info, char* shortname);
|
||||
void CreateShortName (CFileInfo* dir, CFileInfo* info);
|
||||
Bit16u CreateShortNameID (CFileInfo* dir, const char* name);
|
||||
bool SetResult (CFileInfo* dir, char * &result, Bit16u entryNr);
|
||||
bool IsCachedIn (CFileInfo* dir);
|
||||
CFileInfo* FindDirInfo (const char* path, char* expandedPath);
|
||||
bool RemoveSpaces (char* str);
|
||||
bool OpenDir (CFileInfo* dir, char* path, Bit16u& id);
|
||||
void CreateEntry (CFileInfo* dir, const char* name);
|
||||
Bit16u GetFreeID (CFileInfo* dir);
|
||||
void Clear (void);
|
||||
|
||||
|
||||
CFileInfo* dirBase;
|
||||
char dirPath [CROSS_LEN];
|
||||
char basePath [CROSS_LEN];
|
||||
bool dirFirstTime;
|
||||
TDirSort sortDirType;
|
||||
CFileInfo* save_dir;
|
||||
char save_path [CROSS_LEN];
|
||||
char save_expanded [CROSS_LEN];
|
||||
|
||||
Bit16u srchNr;
|
||||
CFileInfo* dirSearch [MAX_OPENDIRS];
|
||||
char dirSearchName [MAX_OPENDIRS];
|
||||
bool free [MAX_OPENDIRS];
|
||||
|
||||
};
|
||||
|
||||
class DOS_No_Drive_Cache {
|
||||
public:
|
||||
DOS_No_Drive_Cache (void) {};
|
||||
DOS_No_Drive_Cache (const char* path);
|
||||
~DOS_No_Drive_Cache (void) {};
|
||||
|
||||
typedef enum TDirSort { NOSORT, ALPHABETICAL, DIRALPHABETICAL, ALPHABETICALREV, DIRALPHABETICALREV };
|
||||
|
||||
void SetBaseDir (const char* path);
|
||||
void SetDirSort (TDirSort sort) {};
|
||||
bool OpenDir (const char* path, Bit16u& id);
|
||||
bool ReadDir (Bit16u id, char * &result);
|
||||
|
||||
void ExpandName (char* path) {};
|
||||
char* GetExpandName (const char* path) { return (char*)path; };
|
||||
bool GetShortName (const char* fullname, char* shortname) { return false; };
|
||||
|
||||
void CacheOut (const char* path, bool ignoreLastDir = false) {};
|
||||
void AddEntry (const char* path, bool checkExists = false) {};
|
||||
void DeleteEntry (const char* path, bool ignoreLastDir = false) {};
|
||||
|
||||
void SetCurrentEntry (Bit16u entry) {};
|
||||
Bit16u GetCurrentEntry (void) { return 0; };
|
||||
|
||||
void EmptyCache (void) {};
|
||||
|
||||
public:
|
||||
char basePath [CROSS_LEN];
|
||||
char dirPath [CROSS_LEN];
|
||||
};
|
||||
|
||||
class DOS_Drive {
|
||||
public:
|
||||
DOS_Drive();
|
||||
@ -88,9 +206,13 @@ public:
|
||||
virtual bool FileExists(const char* name)=0;
|
||||
virtual bool FileStat(const char* name, FileStat_Block * const stat_block)=0;
|
||||
virtual Bit8u GetMediaByte(void)=0;
|
||||
virtual void SetDir(const char* path) { strcpy(curdir,path); };
|
||||
virtual void EmptyCache(void) { dirCache.EmptyCache(); };
|
||||
char * GetInfo(void);
|
||||
char curdir[DOS_PATHLENGTH];
|
||||
char info[256];
|
||||
|
||||
DOS_Drive_Cache dirCache;
|
||||
};
|
||||
|
||||
enum { OPEN_READ=0,OPEN_WRITE=1,OPEN_READWRITE=2 };
|
||||
|
114
include/dosbox.h
114
include/dosbox.h
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2002 The DOSBox Team
|
||||
* Copyright (C) 2002-2003 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -48,11 +48,9 @@ typedef signed int Bits;
|
||||
|
||||
#include <stddef.h>
|
||||
#include "config.h"
|
||||
#include "../settings.h"
|
||||
|
||||
class Section;
|
||||
|
||||
|
||||
typedef Bitu (LoopHandler)(void);
|
||||
|
||||
void DOSBOX_RunMachine();
|
||||
@ -65,101 +63,25 @@ class Config;
|
||||
extern Config * control;
|
||||
extern Bitu errorlevel;
|
||||
|
||||
inline void LOG_MSG(char* message)
|
||||
{
|
||||
if(errorlevel>=0) S_Warn(message);
|
||||
}
|
||||
#define LOG_MSG S_Warn
|
||||
|
||||
template <class type1>
|
||||
inline void LOG_MSG(char* message,type1 arg1)
|
||||
{
|
||||
|
||||
if(errorlevel>=0) S_Warn(message,arg1);
|
||||
}
|
||||
|
||||
template <class type1,class type2>
|
||||
inline void LOG_MSG(char* message,type1 arg1,type2 arg2)
|
||||
{
|
||||
|
||||
if(errorlevel>=0) S_Warn(message,arg1,arg2);
|
||||
}
|
||||
|
||||
template <class type1,class type2, class type3>
|
||||
inline void LOG_MSG(char* message,type1 arg1,type2 arg2,type3 arg3)
|
||||
{
|
||||
|
||||
if (errorlevel>=0)S_Warn(message,arg1,arg2,arg3);
|
||||
}
|
||||
|
||||
#if C_LOGGING
|
||||
inline void LOG_DEBUG(char * message)
|
||||
{
|
||||
|
||||
if(errorlevel>=2) S_Warn(message);
|
||||
}
|
||||
|
||||
template <class type>
|
||||
inline void LOG_DEBUG(char * message, type type1)
|
||||
{
|
||||
|
||||
if(errorlevel>=2) S_Warn(message,type1);
|
||||
}
|
||||
|
||||
template <class type>
|
||||
inline void LOG_WARN(char * message, type type1)
|
||||
{
|
||||
|
||||
if(errorlevel>=1) S_Warn(message,type1);
|
||||
}
|
||||
|
||||
inline void LOG_WARN(char* message)
|
||||
{
|
||||
|
||||
if(errorlevel>=1) S_Warn(message);
|
||||
}
|
||||
|
||||
inline void LOG_ERROR(char * message)
|
||||
{
|
||||
|
||||
if(errorlevel>=0) S_Warn(message);
|
||||
}
|
||||
|
||||
template <class type>
|
||||
inline void LOG_ERROR(char * message, type type1)
|
||||
{
|
||||
|
||||
if(errorlevel>=0) S_Warn(message,type1);
|
||||
}
|
||||
|
||||
template <class type1, class type2>
|
||||
inline void LOG_ERROR(char * message, type1 arg1,type2 arg2)
|
||||
{
|
||||
|
||||
if(errorlevel>=0) S_Warn(message,arg1,arg2);
|
||||
}
|
||||
|
||||
template <class type1, class type2>
|
||||
inline void LOG_WARN(char * message, type1 arg1,type2 arg2)
|
||||
{
|
||||
|
||||
if(errorlevel>=1) S_Warn(message,arg1,arg2);
|
||||
}
|
||||
|
||||
template <class type1, class type2>
|
||||
inline void LOG_DEBUG(char * message, type1 arg1,type2 arg2)
|
||||
{
|
||||
|
||||
if(errorlevel>=2) S_Warn(message,arg1,arg2);
|
||||
}
|
||||
enum LOG_TYPES {
|
||||
LOG_ALL,
|
||||
LOG_VGA, LOG_VGAGFX,LOG_VGAMISC,LOG_INT10,
|
||||
LOG_SB,LOG_DMA,
|
||||
LOG_FPU,LOG_CPU,
|
||||
LOG_FCB,LOG_FILES,LOG_IOCTL,LOG_EXEC,LOG_DOSMISC,
|
||||
LOG_PIT,LOG_KEYBOARD,LOG_PIC,
|
||||
LOG_MOUSE,LOG_BIOS,LOG_GUI,LOG_MISC,
|
||||
LOG_MAX,LOG_ERROR=0x80
|
||||
};
|
||||
|
||||
#if C_DEBUG
|
||||
extern void DEBUG_ShowMsg(Bit32u msgmask, char * msg,...);
|
||||
#define LOG DEBUG_ShowMsg
|
||||
#else
|
||||
#define LOG_DEBUG
|
||||
#define LOG_WARN
|
||||
#define LOG_ERROR
|
||||
#endif
|
||||
#define LOG
|
||||
#endif /* C_DEBUG */
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
#endif /* __DOSBOX_H */
|
||||
|
||||
|
@ -22,4 +22,12 @@ void JOYSTICK_Button(Bitu which,Bitu num,bool pressed);
|
||||
|
||||
void JOYSTICK_Move_X(Bitu which,float x);
|
||||
|
||||
void JOYSTICK_Move_Y(Bitu which,float y);
|
||||
void JOYSTICK_Move_Y(Bitu which,float y);
|
||||
|
||||
bool JOYSTICK_IsEnabled(Bitu which);
|
||||
|
||||
bool JOYSTICK_GetButton(Bitu which, Bitu num);
|
||||
|
||||
float JOYSTICK_GetMove_X(Bitu which);
|
||||
|
||||
float JOYSTICK_GetMove_Y(Bitu which);
|
||||
|
@ -19,17 +19,7 @@
|
||||
#ifndef _KEYBOARD_H_
|
||||
#define _KEYBOARD_H_
|
||||
|
||||
typedef void(KEYBOARD_EventHandler)(void);
|
||||
void KEYBOARD_AddCode(Bit8u code);
|
||||
void KEYBOARD_AddKey(Bitu keytype,bool pressed);
|
||||
void KEYBOARD_AddEvent(Bitu keytype,Bitu state,KEYBOARD_EventHandler * handler);
|
||||
|
||||
|
||||
#define ALT_PRESSED 0x1
|
||||
#define CTRL_PRESSED 0x2
|
||||
#define SHIFT_PRESSED 0x4
|
||||
|
||||
enum {
|
||||
enum KBD_KEYS {
|
||||
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_a, KBD_s, KBD_d, KBD_f, KBD_g, KBD_h, KBD_j, KBD_k, KBD_l, KBD_z,
|
||||
@ -54,4 +44,16 @@ enum {
|
||||
KBD_LAST
|
||||
};
|
||||
|
||||
typedef void(KEYBOARD_EventHandler)(void);
|
||||
|
||||
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
|
||||
|
@ -60,6 +60,33 @@ extern HostPt memory;
|
||||
Working on big or little endian machines
|
||||
*/
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
|
||||
INLINE Bit8u readb(HostPt off) {
|
||||
return off[0];
|
||||
};
|
||||
INLINE Bit16u readw(HostPt off) {
|
||||
return off[0] | (off[1] << 8);
|
||||
};
|
||||
INLINE Bit32u readd(HostPt off) {
|
||||
return off[0] | (off[1] << 8) | (off[2] << 16) | (off[3] << 24);
|
||||
};
|
||||
INLINE void writeb(HostPt off,Bit8u val) {
|
||||
off[0]=val;
|
||||
};
|
||||
INLINE void writew(HostPt off,Bit16u val) {
|
||||
off[0]=(Bit8u)((val & 0x00ff));
|
||||
off[1]=(Bit8u)((val & 0xff00) >> 8);
|
||||
};
|
||||
INLINE void writed(HostPt off,Bit32u val) {
|
||||
off[0]=(Bit8u)((val & 0x000000ff));
|
||||
off[1]=(Bit8u)((val & 0x0000ff00) >> 8);
|
||||
off[2]=(Bit8u)((val & 0x00ff0000) >> 16);
|
||||
off[3]=(Bit8u)((val & 0xff000000) >> 24);
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
INLINE Bit8u readb(HostPt off) {
|
||||
return *(Bit8u *)off;
|
||||
};
|
||||
@ -79,6 +106,7 @@ INLINE void writed(HostPt off,Bit32u val) {
|
||||
*(Bit32u *)(off)=val;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/* The Folowing six functions are slower but they recognize the paged memory system */
|
||||
//TODO maybe make em inline to go a bit faster
|
||||
|
@ -39,7 +39,6 @@ void MIXER_Enable(MIXER_Channel * chan,bool enable);
|
||||
|
||||
/* PC Speakers functions, tightly related to the timer functions */
|
||||
|
||||
void PCSPEAKER_Enable(bool enable);
|
||||
void PCSPEAKER_SetCounter(Bitu cntr,Bitu mode);
|
||||
|
||||
void PCSPEAKER_SetType(Bitu mode);
|
||||
|
||||
|
@ -43,14 +43,30 @@ struct Segment {
|
||||
|
||||
enum SegNames { cs=0,ds,es,fs,gs,ss};
|
||||
|
||||
union GenReg32 {
|
||||
Bit32u dword[1];
|
||||
Bit16u word[2];
|
||||
Bit8u byte[4];
|
||||
};
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
|
||||
#define DW_INDEX 0
|
||||
#define W_INDEX 1
|
||||
#define BH_INDEX 2
|
||||
#define BL_INDEX 3
|
||||
|
||||
#else
|
||||
|
||||
#define DW_INDEX 0
|
||||
#define W_INDEX 0
|
||||
#define BH_INDEX 1
|
||||
#define BL_INDEX 0
|
||||
|
||||
#endif
|
||||
|
||||
struct CPU_Regs {
|
||||
union {
|
||||
Bit32u d;
|
||||
Bit16u w;
|
||||
struct {
|
||||
Bit8u l,h;
|
||||
}b;
|
||||
} regs[8],ip;
|
||||
GenReg32 regs[8],ip;
|
||||
};
|
||||
|
||||
extern Segment Segs[6];
|
||||
@ -87,46 +103,47 @@ enum REG_NUM {
|
||||
};
|
||||
|
||||
//macros to convert a 3-bit register index to the correct register
|
||||
#define reg_8l(reg) (cpu_regs.regs[(reg)].b.l)
|
||||
#define reg_8h(reg) (cpu_regs.regs[(reg)].b.h)
|
||||
#define reg_8l(reg) (cpu_regs.regs[(reg)].byte[BL_INDEX])
|
||||
#define reg_8h(reg) (cpu_regs.regs[(reg)].byte[BH_INDEX])
|
||||
#define reg_8(reg) ((reg) & 4 ? reg_8h((reg) & 3) : reg_8l((reg) & 3))
|
||||
#define reg_16(reg) (cpu_regs.regs[(reg)].w)
|
||||
#define reg_32(reg) (cpu_regs.regs[(reg)].d)
|
||||
#define reg_16(reg) (cpu_regs.regs[(reg)].word[W_INDEX])
|
||||
#define reg_32(reg) (cpu_regs.regs[(reg)].dword[DW_INDEX])
|
||||
|
||||
#define reg_al cpu_regs.regs[REG_NUM_AX].b.l
|
||||
#define reg_ah cpu_regs.regs[REG_NUM_AX].b.h
|
||||
#define reg_ax cpu_regs.regs[REG_NUM_AX].w
|
||||
#define reg_eax cpu_regs.regs[REG_NUM_AX].d
|
||||
|
||||
#define reg_bl cpu_regs.regs[REG_NUM_BX].b.l
|
||||
#define reg_bh cpu_regs.regs[REG_NUM_BX].b.h
|
||||
#define reg_bx cpu_regs.regs[REG_NUM_BX].w
|
||||
#define reg_ebx cpu_regs.regs[REG_NUM_BX].d
|
||||
#define reg_al cpu_regs.regs[REG_NUM_AX].byte[BL_INDEX]
|
||||
#define reg_ah cpu_regs.regs[REG_NUM_AX].byte[BH_INDEX]
|
||||
#define reg_ax cpu_regs.regs[REG_NUM_AX].word[W_INDEX]
|
||||
#define reg_eax cpu_regs.regs[REG_NUM_AX].dword[DW_INDEX]
|
||||
|
||||
#define reg_cl cpu_regs.regs[REG_NUM_CX].b.l
|
||||
#define reg_ch cpu_regs.regs[REG_NUM_CX].b.h
|
||||
#define reg_cx cpu_regs.regs[REG_NUM_CX].w
|
||||
#define reg_ecx cpu_regs.regs[REG_NUM_CX].d
|
||||
#define reg_bl cpu_regs.regs[REG_NUM_BX].byte[BL_INDEX]
|
||||
#define reg_bh cpu_regs.regs[REG_NUM_BX].byte[BH_INDEX]
|
||||
#define reg_bx cpu_regs.regs[REG_NUM_BX].word[W_INDEX]
|
||||
#define reg_ebx cpu_regs.regs[REG_NUM_BX].dword[DW_INDEX]
|
||||
|
||||
#define reg_dl cpu_regs.regs[REG_NUM_DX].b.l
|
||||
#define reg_dh cpu_regs.regs[REG_NUM_DX].b.h
|
||||
#define reg_dx cpu_regs.regs[REG_NUM_DX].w
|
||||
#define reg_edx cpu_regs.regs[REG_NUM_DX].d
|
||||
#define reg_cl cpu_regs.regs[REG_NUM_CX].byte[BL_INDEX]
|
||||
#define reg_ch cpu_regs.regs[REG_NUM_CX].byte[BH_INDEX]
|
||||
#define reg_cx cpu_regs.regs[REG_NUM_CX].word[W_INDEX]
|
||||
#define reg_ecx cpu_regs.regs[REG_NUM_CX].dword[DW_INDEX]
|
||||
|
||||
#define reg_si cpu_regs.regs[REG_NUM_SI].w
|
||||
#define reg_esi cpu_regs.regs[REG_NUM_SI].d
|
||||
#define reg_dl cpu_regs.regs[REG_NUM_DX].byte[BL_INDEX]
|
||||
#define reg_dh cpu_regs.regs[REG_NUM_DX].byte[BH_INDEX]
|
||||
#define reg_dx cpu_regs.regs[REG_NUM_DX].word[W_INDEX]
|
||||
#define reg_edx cpu_regs.regs[REG_NUM_DX].dword[DW_INDEX]
|
||||
|
||||
#define reg_di cpu_regs.regs[REG_NUM_DI].w
|
||||
#define reg_edi cpu_regs.regs[REG_NUM_DI].d
|
||||
#define reg_si cpu_regs.regs[REG_NUM_SI].word[W_INDEX]
|
||||
#define reg_esi cpu_regs.regs[REG_NUM_SI].dword[DW_INDEX]
|
||||
|
||||
#define reg_sp cpu_regs.regs[REG_NUM_SP].w
|
||||
#define reg_esp cpu_regs.regs[REG_NUM_SP].d
|
||||
#define reg_di cpu_regs.regs[REG_NUM_DI].word[W_INDEX]
|
||||
#define reg_edi cpu_regs.regs[REG_NUM_DI].dword[DW_INDEX]
|
||||
|
||||
#define reg_bp cpu_regs.regs[REG_NUM_BP].w
|
||||
#define reg_ebp cpu_regs.regs[REG_NUM_BP].d
|
||||
#define reg_sp cpu_regs.regs[REG_NUM_SP].word[W_INDEX]
|
||||
#define reg_esp cpu_regs.regs[REG_NUM_SP].dword[DW_INDEX]
|
||||
|
||||
#define reg_ip cpu_regs.ip.w
|
||||
#define reg_eip cpu_regs.ip.d
|
||||
#define reg_bp cpu_regs.regs[REG_NUM_BP].word[W_INDEX]
|
||||
#define reg_ebp cpu_regs.regs[REG_NUM_BP].dword[DW_INDEX]
|
||||
|
||||
#define reg_ip cpu_regs.ip.word[W_INDEX]
|
||||
#define reg_eip cpu_regs.ip.dword[DW_INDEX]
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2002 The DOSBox Team
|
||||
* Copyright (C) 2002-2003 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -19,7 +19,8 @@
|
||||
|
||||
|
||||
enum RENDER_Operation {
|
||||
OP_None,OP_2xSai,OP_Scale2x
|
||||
OP_None,OP_Shot,
|
||||
OP_2xSai,OP_Scale2x,
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -29,12 +30,13 @@ enum {
|
||||
DoubleBoth= 0x03
|
||||
};
|
||||
|
||||
bool RENDER_StartUpdate(void);
|
||||
|
||||
void RENDER_EndUpdate(void);
|
||||
|
||||
void RENDER_Part(Bit8u * data,Bitu x,Bitu y,Bitu dx,Bitu dy);
|
||||
typedef void (* RENDER_Part_Handler)(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy);
|
||||
typedef void (* RENDER_Draw_Handler)(RENDER_Part_Handler part_handler);
|
||||
|
||||
void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,float ratio,Bitu flags);
|
||||
void RENDER_DoUpdate(void);
|
||||
|
||||
void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,float ratio,Bitu flags,RENDER_Draw_Handler draw_handler);
|
||||
|
||||
void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue);
|
||||
|
@ -179,7 +179,8 @@ public:
|
||||
void StartUp();
|
||||
void PrintConfig(const char* configfilename);
|
||||
void ParseConfigFile(const char* configfilename);
|
||||
|
||||
void ParseEnv(char ** envp);
|
||||
|
||||
std::list<Section*> sectionlist;
|
||||
typedef std::list<Section*>::iterator it;
|
||||
typedef std::list<Section*>::reverse_iterator reverse_it;
|
||||
|
@ -22,6 +22,8 @@
|
||||
|
||||
typedef void (* GFX_ModeCallBack)(Bitu width,Bitu height,Bitu bpp,Bitu pitch,Bitu flags);
|
||||
|
||||
typedef void (* GFX_DrawCallBack)(void * data);
|
||||
|
||||
struct GFX_PalEntry {
|
||||
Bit8u r;
|
||||
Bit8u g;
|
||||
@ -31,6 +33,8 @@ struct GFX_PalEntry {
|
||||
|
||||
#define GFX_FIXED_BPP 0x01
|
||||
#define GFX_RESIZEABLE 0x02
|
||||
#define GFX_SHADOW 0x04
|
||||
|
||||
|
||||
#define MODE_SET 0x01
|
||||
#define MODE_FULLSCREEN 0x02
|
||||
@ -40,14 +44,13 @@ void GFX_Events(void);
|
||||
void GFX_SetPalette(Bitu start,Bitu count,GFX_PalEntry * entries);
|
||||
|
||||
Bitu GFX_GetRGB(Bit8u red,Bit8u green,Bit8u blue);
|
||||
void GFX_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu flags,GFX_ModeCallBack callback);
|
||||
void GFX_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu flags,GFX_ModeCallBack mode_callback, GFX_DrawCallBack draw_callback);
|
||||
|
||||
void GFX_Start(void);
|
||||
void GFX_Stop(void);
|
||||
void GFX_SwitchFullScreen(void);
|
||||
|
||||
void * GFX_StartUpdate(void);
|
||||
void GFX_EndUpdate(void);
|
||||
void GFX_DoUpdate(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -128,7 +128,7 @@ else
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
|
||||
if [ -f $src -o -d $src ]
|
||||
if [ -f "$src" ] || [ -d "$src" ]
|
||||
then
|
||||
:
|
||||
else
|
||||
|
10
missing
10
missing
@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Common stub for a few missing GNU programs while installing.
|
||||
# Copyright 1996, 1997, 1999, 2000 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1996, 1997, 1999, 2000, 2002 Free Software Foundation, Inc.
|
||||
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
@ -293,23 +293,23 @@ WARNING: \`$1' is missing on your system. You should only need it if
|
||||
# Look for gnutar/gtar before invocation to avoid ugly error
|
||||
# messages.
|
||||
if (gnutar --version > /dev/null 2>&1); then
|
||||
gnutar ${1+"$@"} && exit 0
|
||||
gnutar "$@" && exit 0
|
||||
fi
|
||||
if (gtar --version > /dev/null 2>&1); then
|
||||
gtar ${1+"$@"} && exit 0
|
||||
gtar "$@" && exit 0
|
||||
fi
|
||||
firstarg="$1"
|
||||
if shift; then
|
||||
case "$firstarg" in
|
||||
*o*)
|
||||
firstarg=`echo "$firstarg" | sed s/o//`
|
||||
tar "$firstarg" ${1+"$@"} && exit 0
|
||||
tar "$firstarg" "$@" && exit 0
|
||||
;;
|
||||
esac
|
||||
case "$firstarg" in
|
||||
*h*)
|
||||
firstarg=`echo "$firstarg" | sed s/h//`
|
||||
tar "$firstarg" ${1+"$@"} && exit 0
|
||||
tar "$firstarg" "$@" && exit 0
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
@ -4,8 +4,6 @@
|
||||
# Created: 1993-05-16
|
||||
# Public domain
|
||||
|
||||
# $Id: mkinstalldirs,v 1.13 1999/01/05 03:18:55 bje Exp $
|
||||
|
||||
errstatus=0
|
||||
dirmode=""
|
||||
|
||||
|
43
settings.h
43
settings.h
@ -1,43 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2002 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _SETTINGS_H_
|
||||
#define _SETTINGS_H_
|
||||
|
||||
/* Enable the debugger, under linux/freebsd dosbox must be started in an xterm under X */
|
||||
#define C_DEBUG 0
|
||||
#define C_HEAVY_DEBUG 0
|
||||
|
||||
/* Enable the logging of extra information for debugging to the console */
|
||||
#define C_LOGGING 0
|
||||
|
||||
/* Enable some big compile-time increasing inlines, great for speed though */
|
||||
#define C_EXTRAINLINE 0
|
||||
|
||||
/* Enable the FPU module, still only for beta testing */
|
||||
#define C_FPU 0
|
||||
|
||||
/* Maximum memory range in megabytes */
|
||||
#define C_MEM_MAX_SIZE 12
|
||||
|
||||
/* Enable debug messages for several modules, requires C_LOGGING */
|
||||
#define DEBUG_SBLASTER 0 /* SoundBlaster Debugging*/
|
||||
#define DEBUG_DMA 0 /* DMA Debugging */
|
||||
#define DEBUG_DOS 0 /* DOS Debugging */
|
||||
|
||||
#endif
|
@ -6,5 +6,5 @@ bin_PROGRAMS = dosbox
|
||||
|
||||
dosbox_SOURCES = dosbox.cpp
|
||||
dosbox_LDADD = cpu/libcpu.a debug/libdebug.a dos/libdos.a fpu/libfpu.a hardware/libhardware.a gui/libgui.a \
|
||||
ints/libints.a misc/libmisc.a shell/libshell.a -lcurses -lpng
|
||||
ints/libints.a misc/libmisc.a shell/libshell.a
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Makefile.in generated by automake 1.6.1 from Makefile.am.
|
||||
# Makefile.in generated by automake 1.6.3 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
|
||||
@ -49,6 +49,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = @program_transform_name@
|
||||
@ -64,6 +65,8 @@ host_triplet = @host@
|
||||
EXEEXT = @EXEEXT@
|
||||
OBJEXT = @OBJEXT@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
ALSA_CFLAGS = @ALSA_CFLAGS@
|
||||
ALSA_LIBS = @ALSA_LIBS@
|
||||
AMTAR = @AMTAR@
|
||||
AWK = @AWK@
|
||||
CC = @CC@
|
||||
@ -89,7 +92,7 @@ bin_PROGRAMS = dosbox
|
||||
|
||||
dosbox_SOURCES = dosbox.cpp
|
||||
dosbox_LDADD = cpu/libcpu.a debug/libdebug.a dos/libdos.a fpu/libfpu.a hardware/libhardware.a gui/libgui.a \
|
||||
ints/libints.a misc/libmisc.a shell/libshell.a -lcurses -lpng
|
||||
ints/libints.a misc/libmisc.a shell/libshell.a
|
||||
|
||||
subdir = src
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
@ -146,8 +149,7 @@ install-binPROGRAMS: $(bin_PROGRAMS)
|
||||
p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
|
||||
if test -f $$p \
|
||||
; then \
|
||||
p1=`echo "$$p1" | sed -e 's,^.*/,,'`; \
|
||||
f=`echo $$p1|sed '$(transform);s/$$/$(EXEEXT)/'`; \
|
||||
f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
|
||||
echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f"; \
|
||||
$(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f; \
|
||||
else :; fi; \
|
||||
@ -156,8 +158,7 @@ install-binPROGRAMS: $(bin_PROGRAMS)
|
||||
uninstall-binPROGRAMS:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(bin_PROGRAMS)'; for p in $$list; do \
|
||||
f=`echo $$p|sed 's/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
|
||||
f=`echo "$$f" | sed -e 's,^.*/,,'`; \
|
||||
f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
|
||||
echo " rm -f $(DESTDIR)$(bindir)/$$f"; \
|
||||
rm -f $(DESTDIR)$(bindir)/$$f; \
|
||||
done
|
||||
@ -294,7 +295,7 @@ top_distdir = ..
|
||||
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@for file in $(DISTFILES); do \
|
||||
@list='$(DISTFILES)'; for file in $$list; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
|
||||
@ -353,7 +354,7 @@ mostlyclean-generic:
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]*
|
||||
-rm -f Makefile $(CONFIG_CLEAN_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
|
@ -2,4 +2,4 @@ SUBDIRS = core_16
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||
|
||||
noinst_LIBRARIES = libcpu.a
|
||||
libcpu_a_SOURCES = callback.cpp cpu.cpp flags.cpp modrm.cpp modrm.h slow_16.cpp
|
||||
libcpu_a_SOURCES = callback.cpp cpu.cpp flags.cpp modrm.cpp modrm.h slow_16.cpp instructions.h
|
@ -1,4 +1,4 @@
|
||||
# Makefile.in generated by automake 1.6.1 from Makefile.am.
|
||||
# Makefile.in generated by automake 1.6.3 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
|
||||
@ -49,6 +49,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = @program_transform_name@
|
||||
@ -64,6 +65,8 @@ host_triplet = @host@
|
||||
EXEEXT = @EXEEXT@
|
||||
OBJEXT = @OBJEXT@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
ALSA_CFLAGS = @ALSA_CFLAGS@
|
||||
ALSA_LIBS = @ALSA_LIBS@
|
||||
AMTAR = @AMTAR@
|
||||
AWK = @AWK@
|
||||
CC = @CC@
|
||||
@ -85,7 +88,7 @@ SUBDIRS = core_16
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||
|
||||
noinst_LIBRARIES = libcpu.a
|
||||
libcpu_a_SOURCES = callback.cpp cpu.cpp flags.cpp modrm.cpp modrm.h slow_16.cpp
|
||||
libcpu_a_SOURCES = callback.cpp cpu.cpp flags.cpp modrm.cpp modrm.h slow_16.cpp instructions.h
|
||||
subdir = src/cpu
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
CONFIG_HEADER = $(top_builddir)/config.h
|
||||
@ -278,7 +281,7 @@ top_distdir = ../..
|
||||
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@for file in $(DISTFILES); do \
|
||||
@list='$(DISTFILES)'; for file in $$list; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
|
||||
@ -336,7 +339,7 @@ mostlyclean-generic:
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]*
|
||||
-rm -f Makefile $(CONFIG_CLEAN_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2002 The DOSBox Team
|
||||
* Copyright (C) 2002-2003 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -67,7 +67,7 @@ void CALLBACK_Idle(void) {
|
||||
}
|
||||
|
||||
static Bitu default_handler(void) {
|
||||
LOG_WARN("Illegal Unhandled Interrupt Called %X",lastint);
|
||||
LOG(LOG_ERROR|LOG_CPU,"Illegal Unhandled Interrupt Called %X",lastint);
|
||||
return CBRET_NONE;
|
||||
};
|
||||
|
||||
@ -167,14 +167,13 @@ void CALLBACK_Init(Section* sec) {
|
||||
real_writeb((Bit16u)CB_SEG,(call_idle<<4)+13,0x38);
|
||||
real_writew((Bit16u)CB_SEG,(call_idle<<4)+14,call_idle);
|
||||
|
||||
#if C_DEBUG
|
||||
/* Setup all Interrupt to point to the default handler */
|
||||
call_default=CALLBACK_Allocate();
|
||||
CALLBACK_Setup(call_default,&default_handler,CB_IRET);
|
||||
for (i=0;i<256;i++) {
|
||||
/* Only setup default handler for first half of interrupt table */
|
||||
for (i=0;i<0x40;i++) {
|
||||
real_writed(0,i*4,CALLBACK_RealPointer(call_default));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,3 +1,3 @@
|
||||
|
||||
noinst_HEADERS = helpers.h instructions.h main.h prefix_66.h prefix_of.h start.h stop.h support.h table_ea.h \
|
||||
noinst_HEADERS = helpers.h main.h prefix_66.h prefix_of.h start.h stop.h support.h table_ea.h \
|
||||
prefix_66_of.h
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Makefile.in generated by automake 1.6.1 from Makefile.am.
|
||||
# Makefile.in generated by automake 1.6.3 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
|
||||
@ -49,6 +49,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = @program_transform_name@
|
||||
@ -64,6 +65,8 @@ host_triplet = @host@
|
||||
EXEEXT = @EXEEXT@
|
||||
OBJEXT = @OBJEXT@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
ALSA_CFLAGS = @ALSA_CFLAGS@
|
||||
ALSA_LIBS = @ALSA_LIBS@
|
||||
AMTAR = @AMTAR@
|
||||
AWK = @AWK@
|
||||
CC = @CC@
|
||||
@ -82,7 +85,7 @@ am__include = @am__include@
|
||||
am__quote = @am__quote@
|
||||
install_sh = @install_sh@
|
||||
|
||||
noinst_HEADERS = helpers.h instructions.h main.h prefix_66.h prefix_of.h start.h stop.h support.h table_ea.h \
|
||||
noinst_HEADERS = helpers.h main.h prefix_66.h prefix_of.h start.h stop.h support.h table_ea.h \
|
||||
prefix_66_of.h
|
||||
|
||||
subdir = src/cpu/core_16
|
||||
@ -144,7 +147,7 @@ top_distdir = ../../..
|
||||
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@for file in $(DISTFILES); do \
|
||||
@list='$(DISTFILES)'; for file in $$list; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
|
||||
@ -189,7 +192,7 @@ mostlyclean-generic:
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]*
|
||||
-rm -f Makefile $(CONFIG_CLEAN_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
|
@ -961,7 +961,7 @@ restart:
|
||||
case 0xde: /* FPU ESC 6 */
|
||||
case 0xdf: /* FPU ESC 7 */
|
||||
{
|
||||
LOG_WARN("FPU used");
|
||||
LOG(LOG_CPU,"FPU used");
|
||||
Bit8u rm=Fetchb();
|
||||
if (rm<0xc0) GetEAa;
|
||||
}
|
||||
@ -1037,7 +1037,7 @@ restart:
|
||||
IO_Write(reg_dx+1,reg_ah);
|
||||
break;
|
||||
case 0xf0: /* LOCK */
|
||||
LOG_ERROR("CPU:LOCK");
|
||||
LOG(LOG_CPU,"CPU:LOCK");
|
||||
break;
|
||||
case 0xf1: /* Weird call undocumented */
|
||||
// INTERRUPT(1);
|
||||
|
@ -146,7 +146,7 @@ switch(Fetchb()) {
|
||||
Push_32(reg_esp);Push_32(reg_ebp);Push_32(reg_esi);Push_32(reg_edi);
|
||||
break;
|
||||
case 0x61: /* POPAD */
|
||||
reg_edi=Pop_32();reg_edi=Pop_32();reg_ebp=Pop_32();Pop_32();//Don't save ESP
|
||||
reg_edi=Pop_32();reg_esi=Pop_32();reg_ebp=Pop_32();Pop_32();//Don't save ESP
|
||||
reg_ebx=Pop_32();reg_edx=Pop_32();reg_ecx=Pop_32();reg_eax=Pop_32();
|
||||
break;
|
||||
case 0x64: /* SEG FS: */
|
||||
@ -276,7 +276,7 @@ switch(Fetchb()) {
|
||||
break;
|
||||
}
|
||||
case 0x8c:
|
||||
LOG_WARN("CPU:66:8c looped back");
|
||||
LOG(LOG_CPU,"CPU:66:8c looped back");
|
||||
break;
|
||||
case 0x8d: /* LEA */
|
||||
{
|
||||
|
@ -62,7 +62,7 @@ switch(Fetchb()) {
|
||||
case 0x23: /* MOV DRx,Rd */
|
||||
{
|
||||
GetRM;
|
||||
LOG_DEBUG("CPU:0F:23 does nothing");
|
||||
LOG(LOG_CPU,"CPU:0F:23 does nothing");
|
||||
}
|
||||
break;
|
||||
/* 0x24 MOV Rd,TRx (386) */
|
||||
|
@ -98,7 +98,6 @@ static INLINE Bit32u Pop_32() {
|
||||
#include "helpers.h"
|
||||
#include "table_ea.h"
|
||||
#include "../modrm.h"
|
||||
#include "instructions.h"
|
||||
|
||||
|
||||
static Bit8s table_df_8[2]={1,-1};
|
||||
@ -354,8 +353,8 @@ rep_again:
|
||||
break;
|
||||
default:
|
||||
IPPoint--;
|
||||
LOG_DEBUG("Unhandled REP Prefix %X",Fetchb());
|
||||
|
||||
LOG(LOG_CPU|LOG_ERROR,"Unhandled REP Prefix %X",Fetchb());
|
||||
goto normalexit;
|
||||
}
|
||||
/* If we end up here it's because the CPU_Cycles counter is 0, so restart instruction */
|
||||
IPPoint-=(prefix.count+2); /* Rep instruction and whatever string instruction */
|
||||
|
@ -233,7 +233,7 @@ static EAPoint EA_32_40_n(void) { PrefixReset;return SegBase(ds)+reg_eax+Fetchbs
|
||||
static EAPoint EA_32_41_n(void) { PrefixReset;return SegBase(ds)+reg_ecx+Fetchbs(); }
|
||||
static EAPoint EA_32_42_n(void) { PrefixReset;return SegBase(ds)+reg_edx+Fetchbs(); }
|
||||
static EAPoint EA_32_43_n(void) { PrefixReset;return SegBase(ds)+reg_ebx+Fetchbs(); }
|
||||
static EAPoint EA_32_44_n(void) { PrefixReset;return Sib(1)+Fetchbs();}
|
||||
static EAPoint EA_32_44_n(void) { PrefixReset;EAPoint temp=Sib(1);return temp+Fetchbs();}
|
||||
static EAPoint EA_32_45_n(void) { PrefixReset;return SegBase(ss)+reg_ebp+Fetchbs(); }
|
||||
static EAPoint EA_32_46_n(void) { PrefixReset;return SegBase(ds)+reg_esi+Fetchbs(); }
|
||||
static EAPoint EA_32_47_n(void) { PrefixReset;return SegBase(ds)+reg_edi+Fetchbs(); }
|
||||
@ -242,7 +242,7 @@ static EAPoint EA_32_80_n(void) { PrefixReset;return SegBase(ds)+reg_eax+Fetchds
|
||||
static EAPoint EA_32_81_n(void) { PrefixReset;return SegBase(ds)+reg_ecx+Fetchds(); }
|
||||
static EAPoint EA_32_82_n(void) { PrefixReset;return SegBase(ds)+reg_edx+Fetchds(); }
|
||||
static EAPoint EA_32_83_n(void) { PrefixReset;return SegBase(ds)+reg_ebx+Fetchds(); }
|
||||
static EAPoint EA_32_84_n(void) { PrefixReset;return Sib(2)+Fetchds();}
|
||||
static EAPoint EA_32_84_n(void) { PrefixReset;EAPoint temp=Sib(2);return temp+Fetchbs();}
|
||||
static EAPoint EA_32_85_n(void) { PrefixReset;return SegBase(ss)+reg_ebp+Fetchds(); }
|
||||
static EAPoint EA_32_86_n(void) { PrefixReset;return SegBase(ds)+reg_esi+Fetchds(); }
|
||||
static EAPoint EA_32_87_n(void) { PrefixReset;return SegBase(ds)+reg_edi+Fetchds(); }
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2002 The DOSBox Team
|
||||
* Copyright (C) 2002-2003 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -40,12 +40,14 @@ CPU_Decoder * cpudecoder;
|
||||
static void CPU_CycleIncrease(void) {
|
||||
Bitu old_cycles=CPU_CycleMax;
|
||||
CPU_CycleMax=(Bitu)(CPU_CycleMax*1.2);
|
||||
CPU_CycleLeft=0;CPU_Cycles=0;
|
||||
if (CPU_CycleMax==old_cycles) CPU_CycleMax++;
|
||||
LOG_MSG("CPU:%d cycles",CPU_CycleMax);
|
||||
}
|
||||
|
||||
static void CPU_CycleDecrease(void) {
|
||||
CPU_CycleMax=(Bitu)(CPU_CycleMax/1.2);
|
||||
CPU_CycleLeft=0;CPU_Cycles=0;
|
||||
if (!CPU_CycleMax) CPU_CycleMax=1;
|
||||
LOG_MSG("CPU:%d cycles",CPU_CycleMax);
|
||||
}
|
||||
@ -57,12 +59,12 @@ void Interrupt(Bit8u num) {
|
||||
|
||||
switch (num) {
|
||||
case 0x00:
|
||||
LOG_WARN("Divide Error");
|
||||
LOG(LOG_CPU,"Divide Error");
|
||||
break;
|
||||
case 0x06:
|
||||
break;
|
||||
case 0x07:
|
||||
LOG_WARN("Co Processor Exception");
|
||||
LOG(LOG_FPU,"Co Processor Exception");
|
||||
break;
|
||||
case 0x08:
|
||||
case 0x09:
|
||||
@ -84,7 +86,7 @@ void Interrupt(Bit8u num) {
|
||||
break;
|
||||
case 0xcd:
|
||||
#if C_HEAVY_DEBUG
|
||||
LOG_DEBUG("Call to interrupt 0xCD this is BAD");
|
||||
LOG(LOG_CPU|LOG_ERROR,"Call to interrupt 0xCD this is BAD");
|
||||
DEBUG_HeavyWriteLogInstruction();
|
||||
#endif
|
||||
E_Exit("Call to interrupt 0xCD this is BAD");
|
||||
@ -94,7 +96,7 @@ void Interrupt(Bit8u num) {
|
||||
#endif
|
||||
break;
|
||||
case 0x05:
|
||||
LOG_MSG("CPU:Out Of Bounds interrupt");
|
||||
LOG(LOG_CPU,"CPU:Out Of Bounds interrupt");
|
||||
break;
|
||||
default:
|
||||
// LOG_WARN("Call to unsupported INT %02X call %02X",num,reg_ah);
|
||||
@ -171,8 +173,8 @@ void CPU_Init(Section* sec) {
|
||||
|
||||
SetCPU16bit();
|
||||
|
||||
KEYBOARD_AddEvent(KBD_f11,CTRL_PRESSED,CPU_CycleDecrease);
|
||||
KEYBOARD_AddEvent(KBD_f12,CTRL_PRESSED,CPU_CycleIncrease);
|
||||
KEYBOARD_AddEvent(KBD_f11,KBD_MOD_CTRL,CPU_CycleDecrease);
|
||||
KEYBOARD_AddEvent(KBD_f12,KBD_MOD_CTRL,CPU_CycleIncrease);
|
||||
|
||||
CPU_Cycles=0;
|
||||
CPU_CycleMax=section->Get_int("cycles");;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2002 The DOSBox Team
|
||||
* Copyright (C) 2002-2003 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -134,7 +134,7 @@ bool get_CF(void) {
|
||||
case t_DIV:
|
||||
return false; /* Unkown */
|
||||
default:
|
||||
LOG_WARN("get_CF Unknown %d",flags.type);
|
||||
LOG(LOG_ERROR|LOG_CPU,"get_CF Unknown %d",flags.type);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -229,7 +229,7 @@ again:
|
||||
case t_MUL:
|
||||
return false; /* Unkown */
|
||||
default:
|
||||
LOG_WARN("get_AF Unknown %d",flags.type);
|
||||
LOG(LOG_ERROR|LOG_CPU,"get_AF Unknown %d",flags.type);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -314,7 +314,7 @@ again:
|
||||
case t_MUL:
|
||||
return false; /* Unkown */
|
||||
default:
|
||||
LOG_WARN("get_ZF Unknown %d",flags.type);
|
||||
LOG(LOG_ERROR|LOG_CPU,"get_ZF Unknown %d",flags.type);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -398,7 +398,7 @@ again:
|
||||
case t_MUL:
|
||||
return false; /* Unkown */
|
||||
default:
|
||||
LOG_WARN("get_SF Unkown %d",flags.type);
|
||||
LOG(LOG_ERROR|LOG_CPU,"get_SF Unkown %d",flags.type);
|
||||
}
|
||||
return false;
|
||||
|
||||
@ -539,7 +539,7 @@ again:
|
||||
case t_DIV:
|
||||
return false; /* Unkown */
|
||||
default:
|
||||
LOG_WARN("get_OF Unkown %d",flags.type);
|
||||
LOG(LOG_ERROR|LOG_CPU,"get_OF Unkown %d",flags.type);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2002 The DOSBox Team
|
||||
* Copyright (C) 2002-2003 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -63,6 +63,7 @@ extern Bitu cycle_count;
|
||||
#endif
|
||||
|
||||
|
||||
#include "instructions.h"
|
||||
#include "core_16/support.h"
|
||||
static Bitu CPU_Real_16_Slow_Decode_Trap(void);
|
||||
|
||||
@ -71,16 +72,16 @@ static Bitu CPU_Real_16_Slow_Decode(void) {
|
||||
while (CPU_Cycles>0) {
|
||||
#if C_DEBUG
|
||||
cycle_count++;
|
||||
#endif
|
||||
#if C_HEAVY_DEBUG
|
||||
SAVEIP;
|
||||
if (DEBUG_HeavyIsBreakpoint()) return 1;
|
||||
#endif
|
||||
#endif
|
||||
#include "core_16/main.h"
|
||||
if (prefix.count) {
|
||||
PrefixReset;
|
||||
//DEBUG_HeavyWriteLogInstruction();
|
||||
LOG_DEBUG("Prefix for non prefixed instruction");
|
||||
LOG(LOG_CPU,"Prefix for non prefixed instruction");
|
||||
}
|
||||
CPU_Cycles--;
|
||||
}
|
||||
@ -103,6 +104,7 @@ static Bitu CPU_Real_16_Slow_Decode_Trap(void) {
|
||||
return CBRET_NONE;
|
||||
}
|
||||
|
||||
|
||||
void CPU_Real_16_Slow_Start(void) {
|
||||
cpudecoder=&CPU_Real_16_Slow_Decode;
|
||||
EAPrefixTable[0]=&GetEA_16_n;
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Makefile.in generated by automake 1.6.1 from Makefile.am.
|
||||
# Makefile.in generated by automake 1.6.3 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
|
||||
@ -49,6 +49,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = @program_transform_name@
|
||||
@ -64,6 +65,8 @@ host_triplet = @host@
|
||||
EXEEXT = @EXEEXT@
|
||||
OBJEXT = @OBJEXT@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
ALSA_CFLAGS = @ALSA_CFLAGS@
|
||||
ALSA_LIBS = @ALSA_LIBS@
|
||||
AMTAR = @AMTAR@
|
||||
AWK = @AWK@
|
||||
CC = @CC@
|
||||
@ -209,7 +212,7 @@ top_distdir = ../..
|
||||
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@for file in $(DISTFILES); do \
|
||||
@list='$(DISTFILES)'; for file in $$list; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
|
||||
@ -254,7 +257,7 @@ mostlyclean-generic:
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]*
|
||||
-rm -f Makefile $(CONFIG_CLEAN_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2002 The DOSBox Team
|
||||
* Copyright (C) 2002-2003 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -38,12 +38,18 @@
|
||||
|
||||
#ifdef WIN32
|
||||
void WIN32_Console();
|
||||
#else
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
static struct termios consolesettings;
|
||||
int old_cursor_state;
|
||||
#endif
|
||||
|
||||
// Forwards
|
||||
static void DrawCode(void);
|
||||
static bool DEBUG_Log_Loop(int count);
|
||||
static void DEBUG_RaiseTimerIrq(void);
|
||||
char* AnalyzeInstruction(char* inst);
|
||||
void SaveMemory(Bit16u seg, Bit16u ofs1, Bit32s num);
|
||||
class DEBUG;
|
||||
|
||||
DEBUG* pDebugcom = 0;
|
||||
@ -84,7 +90,37 @@ struct SCodeViewData {
|
||||
|
||||
} codeViewData;
|
||||
|
||||
static Bit16u dataSeg,dataOfs;
|
||||
static Bit16u dataSeg,dataOfs;
|
||||
static bool showExtend = true;
|
||||
|
||||
/********************/
|
||||
/* DebugVar stuff */
|
||||
/********************/
|
||||
|
||||
class CDebugVar
|
||||
{
|
||||
public:
|
||||
CDebugVar(char* _name, PhysPt _adr) { adr=_adr; (strlen(name)<15)?strcpy(name,_name):strncpy(name,_name,15); name[15]=0; };
|
||||
|
||||
char* GetName(void) { return name; };
|
||||
PhysPt GetAdr (void) { return adr; };
|
||||
|
||||
private:
|
||||
PhysPt adr;
|
||||
char name[16];
|
||||
|
||||
public:
|
||||
static void InsertVariable (char* name, PhysPt adr);
|
||||
static CDebugVar* FindVar (PhysPt adr);
|
||||
static void DeleteAll ();
|
||||
static bool SaveVars (char* name);
|
||||
static bool LoadVars (char* name);
|
||||
|
||||
static std::list<CDebugVar*> varList;
|
||||
};
|
||||
|
||||
std::list<CDebugVar*> CDebugVar::varList;
|
||||
|
||||
|
||||
/********************/
|
||||
/* Breakpoint stuff */
|
||||
@ -256,9 +292,8 @@ bool CBreakpoint::CheckBreakpoint(PhysPt adr)
|
||||
Bit8u value = mem_readb(bp->GetLocation());
|
||||
if (bp->GetValue() != value) {
|
||||
// Yup, memory value changed
|
||||
char buffer[200];
|
||||
sprintf(buffer,"DEBUG: Memory breakpoint: %04X:%04X - %02X -> %02X",bp->GetSegment(),bp->GetOffset(),bp->GetValue(),value);
|
||||
LOG_DEBUG(buffer);
|
||||
|
||||
DEBUG_ShowMsg(0,"DEBUG: Memory breakpoint: %04X:%04X - %02X -> %02X",bp->GetSegment(),bp->GetOffset(),bp->GetValue(),value);
|
||||
bp->SetValue(value);
|
||||
return true;
|
||||
};
|
||||
@ -547,8 +582,17 @@ static void DrawCode(void)
|
||||
mvwprintw(dbg.win_code,i,0,"%04X:%04X ",codeViewData.useCS,disEIP);
|
||||
for (c=0;c<size;c++) wprintw(dbg.win_code,"%02X",mem_readb(start+c));
|
||||
for (c=20;c>=size*2;c--) waddch(dbg.win_code,' ');
|
||||
|
||||
char* res = 0;
|
||||
if (showExtend) res = AnalyzeInstruction(dline);
|
||||
waddstr(dbg.win_code,dline);
|
||||
for (c=30-strlen(dline);c>0;c--) waddch(dbg.win_code,' ');
|
||||
for (c=28-strlen(dline);c>0;c--) waddch(dbg.win_code,' ');
|
||||
if (showExtend) {
|
||||
waddstr(dbg.win_code,res);
|
||||
for (c=strlen(res);c<20;c++) waddch(dbg.win_code,' ');
|
||||
} else {
|
||||
for (c=0;c<20;c++) waddch(dbg.win_code,' ');
|
||||
}
|
||||
start+=size;
|
||||
disEIP+=size;
|
||||
|
||||
@ -673,14 +717,73 @@ bool ChangeRegister(char* str)
|
||||
bool ParseCommand(char* str)
|
||||
{
|
||||
char* found = str;
|
||||
while (*found) *found++=toupper(*found);
|
||||
for(char* idx = found;*idx != 0; idx++)
|
||||
*idx = toupper(*idx);
|
||||
|
||||
found = trim(found);
|
||||
|
||||
found = strstr(str,"MEMDUMP ");
|
||||
if (found) { // Insert variable
|
||||
found+=8;
|
||||
Bit16u seg = GetHexValue(found,found); found++;
|
||||
Bit32u ofs = GetHexValue(found,found); found++;
|
||||
Bit32u num = GetHexValue(found,found); found++;
|
||||
SaveMemory(seg,ofs,num);
|
||||
return true;
|
||||
};
|
||||
|
||||
found = strstr(str,"IV ");
|
||||
if (found) { // Insert variable
|
||||
found+=3;
|
||||
Bit16u seg = GetHexValue(found,found); found++;
|
||||
Bit32u ofs = GetHexValue(found,found); found++;
|
||||
char name[16];
|
||||
for (int i=0; i<16; i++) {
|
||||
if ((found[i]!=' ') && (found[i]!=0)) name[i] = found[i];
|
||||
else { name[i] = 0; break; };
|
||||
};
|
||||
name[15] = 0;
|
||||
|
||||
DEBUG_ShowMsg(0,"DEBUG: Created debug var %s at %04X:%04X",name,seg,ofs);
|
||||
CDebugVar::InsertVariable(name,PhysMake(seg,ofs));
|
||||
return true;
|
||||
}
|
||||
|
||||
found = strstr(str,"SV ");
|
||||
if (found) { // Save variables
|
||||
found+=3;
|
||||
char name[13];
|
||||
for (int i=0; i<12; i++) {
|
||||
if ((found[i]!=' ') && (found[i]!=0)) name[i] = found[i];
|
||||
else { name[i] = 0; break; };
|
||||
};
|
||||
name[12] = 0;
|
||||
if (CDebugVar::SaveVars(name)) DEBUG_ShowMsg(0,"DEBUG: Variable list save (%s) : ok.",name);
|
||||
else DEBUG_ShowMsg(0,"DEBUG: Variable list save (%s) : failure",name);
|
||||
return true;
|
||||
}
|
||||
|
||||
found = strstr(str,"LV ");
|
||||
if (found) { // Save variables
|
||||
found+=3;
|
||||
char name[13];
|
||||
for (int i=0; i<12; i++) {
|
||||
if ((found[i]!=' ') && (found[i]!=0)) name[i] = found[i];
|
||||
else { name[i] = 0; break; };
|
||||
};
|
||||
name[12] = 0;
|
||||
if (CDebugVar::LoadVars(name)) DEBUG_ShowMsg(0,"DEBUG: Variable list load (%s) : ok.",name);
|
||||
else DEBUG_ShowMsg(0,"DEBUG: Variable list load (%s) : failure",name);
|
||||
return true;
|
||||
}
|
||||
|
||||
found = strstr(str,"BP ");
|
||||
if (found) { // Add new breakpoint
|
||||
found+=3;
|
||||
Bit16u seg = GetHexValue(found,found);found++; // skip ":"
|
||||
Bit32u ofs = GetHexValue(found,found);
|
||||
CBreakpoint::AddBreakpoint(seg,ofs,false);
|
||||
LOG_DEBUG("DEBUG: Set breakpoint at %04X:%04X",seg,ofs);
|
||||
DEBUG_ShowMsg(0,"DEBUG: Set breakpoint at %04X:%04X",seg,ofs);
|
||||
return true;
|
||||
}
|
||||
#if C_HEAVY_DEBUG
|
||||
@ -690,7 +793,7 @@ bool ParseCommand(char* str)
|
||||
Bit16u seg = GetHexValue(found,found);found++; // skip ":"
|
||||
Bit32u ofs = GetHexValue(found,found);
|
||||
CBreakpoint::AddMemBreakpoint(seg,ofs);
|
||||
LOG_DEBUG("DEBUG: Set memory breakpoint at %04X:%04X",seg,ofs);
|
||||
DEBUG_ShowMsg(0,"DEBUG: Set memory breakpoint at %04X:%04X",seg,ofs);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
@ -701,10 +804,10 @@ bool ParseCommand(char* str)
|
||||
Bit8u valAH = GetHexValue(found,found);
|
||||
if ((valAH==0x00) && (*found=='*')) {
|
||||
CBreakpoint::AddIntBreakpoint(intNr,BPINT_ALL,false);
|
||||
LOG_DEBUG("DEBUG: Set interrupt breakpoint at INT %02X",intNr);
|
||||
DEBUG_ShowMsg(0,"DEBUG: Set interrupt breakpoint at INT %02X",intNr);
|
||||
} else {
|
||||
CBreakpoint::AddIntBreakpoint(intNr,valAH,false);
|
||||
LOG_DEBUG("DEBUG: Set interrupt breakpoint at INT %02X AH=%02X",intNr,valAH);
|
||||
DEBUG_ShowMsg(0,"DEBUG: Set interrupt breakpoint at INT %02X AH=%02X",intNr,valAH);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@ -723,7 +826,7 @@ bool ParseCommand(char* str)
|
||||
Bit8u bpNr = GetHexValue(found,found);
|
||||
if ((bpNr==0x00) && (*found=='*')) { // Delete all
|
||||
CBreakpoint::DeleteAll();
|
||||
LOG_DEBUG("DEBUG: Breakpoints deleted.");
|
||||
DEBUG_ShowMsg(0,"DEBUG: Breakpoints deleted.");
|
||||
} else {
|
||||
// delete single breakpoint
|
||||
CBreakpoint::DeleteByIndex(bpNr);
|
||||
@ -731,36 +834,36 @@ bool ParseCommand(char* str)
|
||||
return true;
|
||||
}
|
||||
found = strstr(str,"C ");
|
||||
if (found) { // Set code overview
|
||||
if (found==(char*)str) { // Set code overview
|
||||
found++;
|
||||
Bit16u codeSeg = GetHexValue(found,found); found++;
|
||||
Bit32u codeOfs = GetHexValue(found,found);
|
||||
LOG_DEBUG("DEBUG: Set code overview to %04X:%04X",codeSeg,codeOfs);
|
||||
DEBUG_ShowMsg(0,"DEBUG: Set code overview to %04X:%04X",codeSeg,codeOfs);
|
||||
codeViewData.useCS = codeSeg;
|
||||
codeViewData.useEIP = codeOfs;
|
||||
return true;
|
||||
}
|
||||
found = strstr(str,"D ");
|
||||
if (found) { // Set data overview
|
||||
if (found==(char*)str) { // Set data overview
|
||||
found++;
|
||||
dataSeg = GetHexValue(found,found); found++;
|
||||
dataOfs = GetHexValue(found,found);
|
||||
LOG_DEBUG("DEBUG: Set data overview to %04X:%04X",dataSeg,dataOfs);
|
||||
DEBUG_ShowMsg(0,"DEBUG: Set data overview to %04X:%04X",dataSeg,dataOfs);
|
||||
return true;
|
||||
}
|
||||
found = strstr(str,"LOG ");
|
||||
if (found) { // Create Cpu log file
|
||||
found+=4;
|
||||
LOG_DEBUG("DEBUG: Starting log");
|
||||
DEBUG_ShowMsg(0,"DEBUG: Starting log");
|
||||
DEBUG_Log_Loop(GetHexValue(found,found));
|
||||
LOG_DEBUG("DEBUG: Logfile LOGCPU.TXT created.");
|
||||
DEBUG_ShowMsg(0,"DEBUG: Logfile LOGCPU.TXT created.");
|
||||
return true;
|
||||
}
|
||||
found = strstr(str,"SR ");
|
||||
if (found) { // Set register value
|
||||
found+=2;
|
||||
if (ChangeRegister(found)) LOG_DEBUG("DEBUG: Set Register success.");
|
||||
else LOG_DEBUG("DEBUG: Set Register failure.");
|
||||
if (ChangeRegister(found)) DEBUG_ShowMsg(0,"DEBUG: Set Register success.");
|
||||
else DEBUG_ShowMsg(0,"DEBUG: Set Register failure.");
|
||||
return true;
|
||||
}
|
||||
found = strstr(str,"SM ");
|
||||
@ -777,14 +880,14 @@ bool ParseCommand(char* str)
|
||||
count++;
|
||||
}
|
||||
};
|
||||
LOG_DEBUG("DEBUG: Memory changed.");
|
||||
DEBUG_ShowMsg(0,"DEBUG: Memory changed.");
|
||||
return true;
|
||||
}
|
||||
found = strstr(str,"INTT ");
|
||||
if (found) { // Create Cpu log file
|
||||
found+=4;
|
||||
Bit8u intNr = GetHexValue(found,found);
|
||||
LOG_DEBUG("DEBUG: Tracing INT %02X",intNr);
|
||||
DEBUG_ShowMsg(0,"DEBUG: Tracing INT %02X",intNr);
|
||||
Interrupt(intNr);
|
||||
SetCodeWinStart();
|
||||
return true;
|
||||
@ -793,7 +896,7 @@ bool ParseCommand(char* str)
|
||||
if (found) { // Create Cpu log file
|
||||
found+=4;
|
||||
Bit8u intNr = GetHexValue(found,found);
|
||||
LOG_DEBUG("DEBUG: Starting INT %02X",intNr);
|
||||
DEBUG_ShowMsg(0,"DEBUG: Starting INT %02X",intNr);
|
||||
CBreakpoint::AddBreakpoint (SegValue(cs),reg_eip, true);
|
||||
CBreakpoint::ActivateBreakpoints(SegPhys(cs)+reg_eip-1,true);
|
||||
debugging=false;
|
||||
@ -801,13 +904,14 @@ bool ParseCommand(char* str)
|
||||
DOSBOX_SetNormalLoop();
|
||||
Interrupt(intNr);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#if C_HEAVY_DEBUG
|
||||
found = strstr(str,"HEAVYLOG");
|
||||
if (found) { // Create Cpu log file
|
||||
logHeavy = !logHeavy;
|
||||
if (logHeavy) LOG_DEBUG("DEBUG: Heavy cpu logging on.");
|
||||
else LOG_DEBUG("DEBUG: Heavy cpu logging off.");
|
||||
if (logHeavy) DEBUG_ShowMsg(0,"DEBUG: Heavy cpu logging on.");
|
||||
else DEBUG_ShowMsg(0,"DEBUG: Heavy cpu logging off.");
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
@ -821,6 +925,7 @@ bool ParseCommand(char* str)
|
||||
wprintw(dbg.win_out,"Return - Enable command line input\n");
|
||||
wprintw(dbg.win_out,"D/E/S/X/B - Set data view to DS:SI/ES:DI/SS:SP/DS:DX/ES:BX\n");
|
||||
wprintw(dbg.win_out,"R/F - Scroll data view\n");
|
||||
wprintw(dbg.win_out,"V - Toggle additional info\n");
|
||||
wprintw(dbg.win_out,"Debugger commands (enter all values in hex or as register):\n");
|
||||
wprintw(dbg.win_out,"--------------------------------------------------------------------------\n");
|
||||
wprintw(dbg.win_out,"BP [segment]:[offset] - Set breakpoint\n");
|
||||
@ -839,13 +944,93 @@ bool ParseCommand(char* str)
|
||||
#endif
|
||||
wprintw(dbg.win_out,"SR [reg] [value] - Set register value\n");
|
||||
wprintw(dbg.win_out,"SM [seg]:[off] [val] [.]..- Set memory with following values\n");
|
||||
|
||||
wprintw(dbg.win_out,"IV [seg]:[off] [name] - Create var name for memory address\n");
|
||||
wprintw(dbg.win_out,"SV [filename] - Save var list in file\n");
|
||||
wprintw(dbg.win_out,"LV [seg]:[off] [name] - Load var list from file\n");
|
||||
|
||||
wprintw(dbg.win_out,"MEMDUMP [seg]:[off] [len] - Write memory to file memdump.txt\n");
|
||||
wprintw(dbg.win_out,"H - Help\n");
|
||||
|
||||
wrefresh(dbg.win_out);
|
||||
return TRUE;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
char* AnalyzeInstruction(char* inst)
|
||||
{
|
||||
static char result[256];
|
||||
|
||||
char instu[256];
|
||||
char prefix[3];
|
||||
Bit16u seg;
|
||||
|
||||
strcpy(instu,inst);
|
||||
upcase(instu);
|
||||
|
||||
result[0] = 0;
|
||||
char* pos = strchr(instu,'[');
|
||||
if (pos) {
|
||||
// Segment prefix ?
|
||||
if (*(pos-1)==':') {
|
||||
char* segpos = pos-3;
|
||||
prefix[0] = tolower(*segpos);
|
||||
prefix[1] = tolower(*(segpos+1));
|
||||
prefix[2] = 0;
|
||||
seg = GetHexValue(segpos,segpos);
|
||||
} else {
|
||||
if (strstr(pos,"SP") || strstr(pos,"BP")) {
|
||||
seg = SegValue(ss);
|
||||
strcpy(prefix,"ss");
|
||||
} else {
|
||||
seg = SegValue(ds);
|
||||
strcpy(prefix,"ds");
|
||||
};
|
||||
};
|
||||
|
||||
pos++;
|
||||
Bit32u adr = GetHexValue(pos,pos);
|
||||
while (*pos!=']') {
|
||||
if (*pos=='+') {
|
||||
pos++;
|
||||
adr += GetHexValue(pos,pos);
|
||||
} else if (*pos=='-') {
|
||||
pos++;
|
||||
adr -= GetHexValue(pos,pos);
|
||||
} else
|
||||
pos++;
|
||||
};
|
||||
switch (DasmLastOperandSize()) {
|
||||
case 8 : { Bit8u val = mem_readb( PhysMake (seg,adr) );
|
||||
sprintf(result,"%s:[%04X]=%02X",prefix,adr,val);
|
||||
} break;
|
||||
case 16: { Bit16u val = mem_readw( PhysMake (seg,adr) );
|
||||
sprintf(result,"%s:[%04X]=%04X",prefix,adr,val);
|
||||
} break;
|
||||
case 32: { Bit32u val = mem_readd( PhysMake (seg,adr) );
|
||||
sprintf(result,"%s:[%04X]=%08X",prefix,adr,val);
|
||||
} break;
|
||||
}
|
||||
// Variable found ?
|
||||
CDebugVar* var = CDebugVar::FindVar(PhysMake(seg,adr));
|
||||
if (var) {
|
||||
// Replace occurance
|
||||
char* pos1 = strchr(inst,'[');
|
||||
char* pos2 = strchr(inst,']');
|
||||
if (pos1 && pos2) {
|
||||
char temp[256];
|
||||
strcpy(temp,pos2); // save end
|
||||
pos1++; *pos1 = 0; // cut after '['
|
||||
strcat(inst,var->GetName()); // add var name
|
||||
strcat(inst,temp); // add end
|
||||
};
|
||||
};
|
||||
};
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
Bit32u DEBUG_CheckKeys(void) {
|
||||
|
||||
if (codeViewData.inputMode) {
|
||||
@ -855,6 +1040,7 @@ Bit32u DEBUG_CheckKeys(void) {
|
||||
case 0x0A: codeViewData.inputMode = FALSE;
|
||||
ParseCommand(codeViewData.inputStr);
|
||||
break;
|
||||
case 0x107: //backspace (linux)
|
||||
case 0x08: // delete
|
||||
if (strlen(codeViewData.inputStr)>0) codeViewData.inputStr[strlen(codeViewData.inputStr)-1] = 0;
|
||||
break;
|
||||
@ -920,7 +1106,9 @@ Bit32u DEBUG_CheckKeys(void) {
|
||||
ParseCommand(codeViewData.inputStr);
|
||||
break;
|
||||
case 'T' : DEBUG_RaiseTimerIrq();
|
||||
LOG_DEBUG("Debug: Timer Int started.");
|
||||
DEBUG_ShowMsg(0,"Debug: Timer Int started.");
|
||||
break;
|
||||
case 'V' : showExtend = !showExtend;
|
||||
break;
|
||||
|
||||
case 0x0A : // Return : input
|
||||
@ -1011,13 +1199,21 @@ static void DEBUG_RaiseTimerIrq(void) {
|
||||
|
||||
static void LogInstruction(Bit16u segValue, Bit32u eipValue, char* buffer)
|
||||
{
|
||||
static char empty[15] = { 32,32,32,32,32,32,32,32,32,32,32,32,32,32,0 };
|
||||
|
||||
PhysPt start = PhysMake(segValue,eipValue);
|
||||
char dline[200];Bitu size;
|
||||
size = DasmI386(dline, start, reg_eip, false);
|
||||
Bitu len = strlen(dline);
|
||||
char* res = empty;
|
||||
if (showExtend) {
|
||||
res = AnalyzeInstruction(dline);
|
||||
if (!res || (strlen(res)==0)) res = empty;
|
||||
};
|
||||
|
||||
if (len<30) for (Bitu i=0; i<30-len; i++) strcat(dline," ");
|
||||
// Get register values
|
||||
sprintf(buffer,"%04X:%08X %s EAX:%08X EBX:%08X ECX:%08X EDX:%08X ESI:%08X EDI:%08X EBP:%08X ESP:%08X DS:%04X ES:%04X FS:%04X GS:%04X SS:%04X CF:%01X ZF:%01X SF:%01X OF:%01X AF:%01X PF:%01X\n",segValue,eipValue,dline,reg_eax,reg_ebx,reg_ecx,reg_edx,reg_esi,reg_edi,reg_ebp,reg_esp,SegValue(ds),SegValue(es),SegValue(fs),SegValue(gs),SegValue(ss),get_CF(),get_ZF(),get_SF(),get_OF(),get_AF(),get_PF());
|
||||
sprintf(buffer,"%04X:%08X %s %s EAX:%08X EBX:%08X ECX:%08X EDX:%08X ESI:%08X EDI:%08X EBP:%08X ESP:%08X DS:%04X ES:%04X FS:%04X GS:%04X SS:%04X CF:%01X ZF:%01X SF:%01X OF:%01X AF:%01X PF:%01X\n",segValue,eipValue,dline,res,reg_eax,reg_ebx,reg_ecx,reg_edx,reg_esi,reg_edi,reg_ebp,reg_esp,SegValue(ds),SegValue(es),SegValue(fs),SegValue(gs),SegValue(ss),get_CF(),get_ZF(),get_SF(),get_OF(),get_AF(),get_PF());
|
||||
};
|
||||
|
||||
static bool DEBUG_Log_Loop(int count) {
|
||||
@ -1126,9 +1322,10 @@ void DEBUG_SetupConsole(void)
|
||||
{
|
||||
#ifdef WIN32
|
||||
WIN32_Console();
|
||||
#else
|
||||
printf("\e[8;50;80t"); //resize terminal
|
||||
fflush(NULL);
|
||||
#else
|
||||
tcgetattr(0,&consolesettings);
|
||||
printf("\e[8;50;80t"); //resize terminal
|
||||
fflush(NULL);
|
||||
#endif
|
||||
memset((void *)&dbg,0,sizeof(dbg));
|
||||
debugging=false;
|
||||
@ -1141,6 +1338,13 @@ void DEBUG_SetupConsole(void)
|
||||
static void DEBUG_ShutDown(Section * sec)
|
||||
{
|
||||
CBreakpoint::DeleteAll();
|
||||
CDebugVar::DeleteAll();
|
||||
#ifndef WIN32
|
||||
curs_set(old_cursor_state);
|
||||
tcsetattr(0, TCSANOW,&consolesettings);
|
||||
printf("\e[0m\e[2J");
|
||||
fflush(NULL);
|
||||
#endif
|
||||
};
|
||||
|
||||
void DEBUG_Init(Section* sec) {
|
||||
@ -1158,18 +1362,120 @@ void DEBUG_Init(Section* sec) {
|
||||
sec->AddDestroyFunction(&DEBUG_ShutDown);
|
||||
}
|
||||
|
||||
// DEBUGGING VAR STUFF
|
||||
|
||||
void CDebugVar::InsertVariable(char* name, PhysPt adr)
|
||||
{
|
||||
varList.push_back(new CDebugVar(name,adr));
|
||||
};
|
||||
|
||||
void CDebugVar::DeleteAll(void)
|
||||
{
|
||||
std::list<CDebugVar*>::iterator i;
|
||||
CDebugVar* bp;
|
||||
for(i=varList.begin(); i != varList.end(); i++) {
|
||||
bp = static_cast<CDebugVar*>(*i);
|
||||
delete bp;
|
||||
};
|
||||
(varList.clear)();
|
||||
};
|
||||
|
||||
CDebugVar* CDebugVar::FindVar(PhysPt pt)
|
||||
{
|
||||
std::list<CDebugVar*>::iterator i;
|
||||
CDebugVar* bp;
|
||||
for(i=varList.begin(); i != varList.end(); i++) {
|
||||
bp = static_cast<CDebugVar*>(*i);
|
||||
if (bp->GetAdr()==pt) return bp;
|
||||
};
|
||||
return 0;
|
||||
};
|
||||
|
||||
bool CDebugVar::SaveVars(char* name)
|
||||
{
|
||||
FILE* f = fopen(name,"wb+");
|
||||
if (!f) return false;
|
||||
|
||||
// write number of vars
|
||||
Bit16u num = varList.size();
|
||||
fwrite(&num,1,sizeof(num),f);
|
||||
|
||||
std::list<CDebugVar*>::iterator i;
|
||||
CDebugVar* bp;
|
||||
for(i=varList.begin(); i != varList.end(); i++) {
|
||||
bp = static_cast<CDebugVar*>(*i);
|
||||
// name
|
||||
fwrite(bp->GetName(),1,16,f);
|
||||
// adr
|
||||
PhysPt adr = bp->GetAdr();
|
||||
fwrite(&adr,1,sizeof(adr),f);
|
||||
};
|
||||
fclose(f);
|
||||
return true;
|
||||
};
|
||||
|
||||
bool CDebugVar::LoadVars(char* name)
|
||||
{
|
||||
FILE* f = fopen(name,"rb");
|
||||
if (!f) return false;
|
||||
|
||||
// read number of vars
|
||||
Bit16u num;
|
||||
fread(&num,1,sizeof(num),f);
|
||||
|
||||
for (Bit16u i=0; i<num; i++) {
|
||||
char name[16];
|
||||
// name
|
||||
fread(name,1,16,f);
|
||||
// adr
|
||||
PhysPt adr;
|
||||
fread(&adr,1,sizeof(adr),f);
|
||||
// insert
|
||||
InsertVariable(name,adr);
|
||||
};
|
||||
fclose(f);
|
||||
return true;
|
||||
};
|
||||
|
||||
void SaveMemory(Bit16u seg, Bit16u ofs1, Bit32s num)
|
||||
{
|
||||
FILE* f = fopen("MEMDUMP.TXT","wt");
|
||||
if (!f) {
|
||||
DEBUG_ShowMsg(0,"DEBUG: Memory dump failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
char buffer[128];
|
||||
char temp[16];
|
||||
|
||||
while(num>0) {
|
||||
|
||||
sprintf(buffer,"%04X:%04X ",seg,ofs1);
|
||||
for (Bit16u x=0; x<16; x++) {
|
||||
sprintf (temp,"%02X ",mem_readb(PhysMake(seg,ofs1+x)));
|
||||
strcat (buffer,temp);
|
||||
};
|
||||
ofs1+=16;
|
||||
num-=16;
|
||||
|
||||
fprintf(f,"%s\n",buffer);
|
||||
};
|
||||
fclose(f);
|
||||
DEBUG_ShowMsg(0,"DEBUG: Memory dump success.");
|
||||
};
|
||||
|
||||
// HEAVY DEBUGGING STUFF
|
||||
|
||||
#if C_HEAVY_DEBUG
|
||||
|
||||
const Bit16u LOGCPUMAX = 200;
|
||||
const Bit32u LOGCPUMAX = 200;
|
||||
|
||||
static Bit16u logCpuCS [LOGCPUMAX];
|
||||
static Bit32u logCpuEIP[LOGCPUMAX];
|
||||
static Bit32u logCount = 0;
|
||||
|
||||
typedef struct SLogInst {
|
||||
char buffer[256];
|
||||
char buffer[512];
|
||||
} TLogInst;
|
||||
|
||||
TLogInst logInst[LOGCPUMAX];
|
||||
@ -1177,22 +1483,26 @@ TLogInst logInst[LOGCPUMAX];
|
||||
void DEBUG_HeavyLogInstruction(void)
|
||||
{
|
||||
LogInstruction(SegValue(cs),reg_eip,logInst[logCount++].buffer);
|
||||
if (logCount>=LOGCPUMAX) logCount = 0;
|
||||
if (logCount>=LOGCPUMAX) {
|
||||
logCount = 0;
|
||||
};
|
||||
};
|
||||
|
||||
void DEBUG_HeavyWriteLogInstruction(void)
|
||||
{
|
||||
if (!logHeavy) return;
|
||||
|
||||
logHeavy = false;
|
||||
|
||||
LOG_DEBUG("DEBUG: Creating cpu log LOGCPU_INT_CD.TXT");
|
||||
DEBUG_ShowMsg(0,"DEBUG: Creating cpu log LOGCPU_INT_CD.TXT");
|
||||
|
||||
FILE* f = fopen("LOGCPU_INT_CD.TXT","wt");
|
||||
if (!f) {
|
||||
LOG_DEBUG("DEBUG: Failed.");
|
||||
DEBUG_ShowMsg(0,"DEBUG: Failed.");
|
||||
return;
|
||||
}
|
||||
|
||||
Bit16u startLog = logCount;
|
||||
Bit32u startLog = logCount;
|
||||
do {
|
||||
// Write Intructions
|
||||
fprintf(f,"%s",logInst[startLog++].buffer);
|
||||
@ -1201,7 +1511,7 @@ void DEBUG_HeavyWriteLogInstruction(void)
|
||||
|
||||
fclose(f);
|
||||
|
||||
LOG_DEBUG("DEBUG: Done.");
|
||||
DEBUG_ShowMsg(0,"DEBUG: Done.");
|
||||
};
|
||||
|
||||
bool DEBUG_HeavyIsBreakpoint(void)
|
||||
@ -1213,8 +1523,9 @@ bool DEBUG_HeavyIsBreakpoint(void)
|
||||
skipFirstInstruction = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
PhysPt where = SegPhys(cs)+reg_eip;
|
||||
|
||||
if (CBreakpoint::CheckBreakpoint(where)) {
|
||||
exitLoop = true;
|
||||
DEBUG_Enable();
|
||||
@ -1227,3 +1538,4 @@ bool DEBUG_HeavyIsBreakpoint(void)
|
||||
|
||||
#endif // DEBUG
|
||||
|
||||
|
||||
|
@ -1111,5 +1111,11 @@ Bitu DasmI386(char* buffer, PhysPt pc, Bitu cur_ip, bool bit32)
|
||||
return getbyte_mac-pc;
|
||||
}
|
||||
|
||||
int DasmLastOperandSize()
|
||||
{
|
||||
return opsize;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2002 The DOSBox Team
|
||||
* Copyright (C) 2002-2003 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -20,24 +20,43 @@
|
||||
|
||||
#include "dosbox.h"
|
||||
#if C_DEBUG
|
||||
|
||||
#include "setup.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <curses.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "support.h"
|
||||
#include "regs.h"
|
||||
#include "debug.h"
|
||||
#include "debug_inc.h"
|
||||
|
||||
void DEBUG_ShowMsg(char * msg) {
|
||||
char buf[1024];
|
||||
strcpy(buf,msg);
|
||||
struct _LogGroup {
|
||||
char * front;
|
||||
bool enabled;
|
||||
};
|
||||
|
||||
waddstr(dbg.win_out,buf);
|
||||
wprintw(dbg.win_out," %d\n",cycle_count);
|
||||
namespace {
|
||||
_LogGroup loggrp[LOG_MAX]={"",true,0};
|
||||
|
||||
FILE* debuglog;
|
||||
};
|
||||
|
||||
extern int old_cursor_state;
|
||||
void DEBUG_ShowMsg(Bit32u entry, char * format,...) {
|
||||
|
||||
if (!(entry & LOG_ERROR) && entry && !loggrp[entry].enabled) return;
|
||||
|
||||
char buf[1024];
|
||||
strcpy(buf,loggrp[entry&127].front);
|
||||
va_list msg;
|
||||
va_start(msg,format);
|
||||
vsprintf(&buf[strlen(buf)],format,msg);
|
||||
va_end(msg);
|
||||
wprintw(dbg.win_out,"%10d: %s\n",cycle_count,buf);
|
||||
wrefresh(dbg.win_out);
|
||||
if(debuglog) fprintf(debuglog,"%10d: %s\n",cycle_count,buf);
|
||||
}
|
||||
|
||||
|
||||
@ -113,24 +132,87 @@ static void MakePairs(void) {
|
||||
init_pair(PAIR_BLACK_GREY, COLOR_BLACK /*| FOREGROUND_INTENSITY */, COLOR_WHITE);
|
||||
init_pair(PAIR_GREY_RED, COLOR_WHITE/*| FOREGROUND_INTENSITY */, COLOR_RED);
|
||||
}
|
||||
static void LOG_Destroy(Section* sec) {
|
||||
|
||||
if(debuglog) fclose(debuglog);
|
||||
}
|
||||
|
||||
static void LOG_Init(Section * sec) {
|
||||
Section_prop * sect=static_cast<Section_prop *>(sec);
|
||||
const char * blah=sect->Get_string("logfile");
|
||||
if(blah && blah[0] &&(debuglog = fopen(blah,"wt+"))){
|
||||
}else{
|
||||
debuglog=0;
|
||||
}
|
||||
sect->AddDestroyFunction(LOG_Destroy);
|
||||
char buf[1024];
|
||||
for (Bitu i=1;i<LOG_MAX;i++) {
|
||||
strcpy(buf,loggrp[i].front);
|
||||
buf[strlen(buf)-1]=0;
|
||||
loggrp[i].enabled=sect->Get_bool(buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LOG_StartUp(void) {
|
||||
/* Setup logging groups */
|
||||
loggrp[LOG_VGA].front="VGA:";
|
||||
loggrp[LOG_VGAGFX].front="VGAGFX:";
|
||||
loggrp[LOG_VGAMISC].front="VGAMISC:";
|
||||
loggrp[LOG_INT10].front="INT10:";
|
||||
loggrp[LOG_SB].front="SBLASTER:";
|
||||
loggrp[LOG_DMA].front="DMA:";
|
||||
|
||||
loggrp[LOG_FPU].front="FPU:";
|
||||
loggrp[LOG_CPU].front="CPU:";
|
||||
|
||||
loggrp[LOG_FCB].front="FCB:";
|
||||
loggrp[LOG_FILES].front="FILES:";
|
||||
loggrp[LOG_IOCTL].front="IOCTL:";
|
||||
loggrp[LOG_EXEC].front="EXEC";
|
||||
loggrp[LOG_DOSMISC].front="DOSMISC:";
|
||||
|
||||
loggrp[LOG_PIT].front="PIT:";
|
||||
loggrp[LOG_KEYBOARD].front="KEYBOARD:";
|
||||
loggrp[LOG_PIC].front="PIC:";
|
||||
|
||||
loggrp[LOG_MOUSE].front="MOUSE:";
|
||||
loggrp[LOG_BIOS].front="BIOS:";
|
||||
loggrp[LOG_GUI].front="GUI:";
|
||||
loggrp[LOG_MISC].front="MISC:";
|
||||
|
||||
/* Register the log section */
|
||||
Section_prop * sect=control->AddSection_prop("log",LOG_Init);
|
||||
sect->Add_string("logfile","");
|
||||
char buf[1024];
|
||||
for (Bitu i=1;i<LOG_MAX;i++) {
|
||||
strcpy(buf,loggrp[i].front);
|
||||
buf[strlen(buf)-1]=0;
|
||||
lowcase(buf);
|
||||
sect->Add_bool(buf,true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void DBGUI_StartUp(void) {
|
||||
/* Start the main window */
|
||||
dbg.win_main=initscr();
|
||||
cbreak(); /* take input chars one at a time, no wait for \n */
|
||||
noecho(); /* don't echo input */
|
||||
cbreak(); /* take input chars one at a time, no wait for \n */
|
||||
noecho(); /* don't echo input */
|
||||
nodelay(dbg.win_main,true);
|
||||
keypad(dbg.win_main,true);
|
||||
#ifndef WIN32
|
||||
resizeterm(50,80);
|
||||
touchwin(dbg.win_main);
|
||||
#endif
|
||||
#ifndef WIN32
|
||||
resizeterm(50,80);
|
||||
touchwin(dbg.win_main);
|
||||
old_cursor_state = curs_set(0);
|
||||
#endif
|
||||
start_color();
|
||||
cycle_count=0;
|
||||
MakePairs();
|
||||
MakeSubWindows();
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -37,6 +37,7 @@ struct DBGBlock {
|
||||
WINDOW * win_out; /* Text Output Window */
|
||||
Bit32u active_win; /* Current active window */
|
||||
Bit32u input_y;
|
||||
Bit32u global_mask; /* Current msgmask */
|
||||
};
|
||||
|
||||
|
||||
@ -53,3 +54,4 @@ extern DBGBlock dbg;
|
||||
|
||||
/* Local Debug Stuff */
|
||||
Bitu DasmI386(char* buffer, PhysPt pc, Bitu cur_ip, bool bit32);
|
||||
int DasmLastOperandSize(void);
|
@ -1,7 +1,9 @@
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||
|
||||
noinst_LIBRARIES = libdos.a
|
||||
EXTRA_DIST = Ntddcdrm.h Ntddscsi.h Ntddstor.h scsidefs.h wnaspi32.h
|
||||
libdos_a_SOURCES = dos.cpp dos_devices.cpp dos_execute.cpp dos_files.cpp dos_ioctl.cpp dos_memory.cpp \
|
||||
dos_misc.cpp dos_classes.cpp dos_programs.cpp dos_tables.cpp \
|
||||
drives.cpp drives.h drive_virtual.cpp drive_local.cpp \
|
||||
dev_con.h
|
||||
drives.cpp drives.h drive_virtual.cpp drive_local.cpp drive_cache.cpp \
|
||||
dev_con.h dos_mscdex.cpp \
|
||||
cdrom.h cdrom.cpp cdrom_ioctl_win32.cpp cdrom_aspi_win32.cpp
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Makefile.in generated by automake 1.6.1 from Makefile.am.
|
||||
# Makefile.in generated by automake 1.6.3 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
|
||||
@ -49,6 +49,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = @program_transform_name@
|
||||
@ -64,6 +65,8 @@ host_triplet = @host@
|
||||
EXEEXT = @EXEEXT@
|
||||
OBJEXT = @OBJEXT@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
ALSA_CFLAGS = @ALSA_CFLAGS@
|
||||
ALSA_LIBS = @ALSA_LIBS@
|
||||
AMTAR = @AMTAR@
|
||||
AWK = @AWK@
|
||||
CC = @CC@
|
||||
@ -84,10 +87,12 @@ install_sh = @install_sh@
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||
|
||||
noinst_LIBRARIES = libdos.a
|
||||
EXTRA_DIST = Ntddcdrm.h Ntddscsi.h Ntddstor.h scsidefs.h wnaspi32.h
|
||||
libdos_a_SOURCES = dos.cpp dos_devices.cpp dos_execute.cpp dos_files.cpp dos_ioctl.cpp dos_memory.cpp \
|
||||
dos_misc.cpp dos_classes.cpp dos_programs.cpp dos_tables.cpp \
|
||||
drives.cpp drives.h drive_virtual.cpp drive_local.cpp \
|
||||
dev_con.h
|
||||
drives.cpp drives.h drive_virtual.cpp drive_local.cpp drive_cache.cpp \
|
||||
dev_con.h dos_mscdex.cpp \
|
||||
cdrom.h cdrom.cpp cdrom_ioctl_win32.cpp cdrom_aspi_win32.cpp
|
||||
|
||||
subdir = src/dos
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
@ -101,7 +106,9 @@ am_libdos_a_OBJECTS = dos.$(OBJEXT) dos_devices.$(OBJEXT) \
|
||||
dos_execute.$(OBJEXT) dos_files.$(OBJEXT) dos_ioctl.$(OBJEXT) \
|
||||
dos_memory.$(OBJEXT) dos_misc.$(OBJEXT) dos_classes.$(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) \
|
||||
cdrom_ioctl_win32.$(OBJEXT) cdrom_aspi_win32.$(OBJEXT)
|
||||
libdos_a_OBJECTS = $(am_libdos_a_OBJECTS)
|
||||
|
||||
DEFS = @DEFS@
|
||||
@ -111,12 +118,17 @@ LDFLAGS = @LDFLAGS@
|
||||
LIBS = @LIBS@
|
||||
depcomp = $(SHELL) $(top_srcdir)/depcomp
|
||||
am__depfiles_maybe = depfiles
|
||||
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/dos.Po ./$(DEPDIR)/dos_classes.Po \
|
||||
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/cdrom.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/cdrom_aspi_win32.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/cdrom_ioctl_win32.Po ./$(DEPDIR)/dos.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/dos_classes.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/dos_devices.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/dos_execute.Po ./$(DEPDIR)/dos_files.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/dos_ioctl.Po ./$(DEPDIR)/dos_memory.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/dos_misc.Po ./$(DEPDIR)/dos_programs.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/dos_misc.Po ./$(DEPDIR)/dos_mscdex.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/dos_programs.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/dos_tables.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/drive_cache.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/drive_local.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/drive_virtual.Po ./$(DEPDIR)/drives.Po
|
||||
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||
@ -159,6 +171,9 @@ mostlyclean-compile:
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdrom.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdrom_aspi_win32.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cdrom_ioctl_win32.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dos.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dos_classes.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dos_devices.Po@am__quote@
|
||||
@ -167,8 +182,10 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dos_ioctl.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dos_memory.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dos_misc.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dos_mscdex.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)/drive_cache.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)/drives.Po@am__quote@
|
||||
@ -231,7 +248,7 @@ top_distdir = ../..
|
||||
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@for file in $(DISTFILES); do \
|
||||
@list='$(DISTFILES)'; for file in $$list; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
|
||||
@ -276,7 +293,7 @@ mostlyclean-generic:
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]*
|
||||
-rm -f Makefile $(CONFIG_CLEAN_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
|
548
src/dos/Ntddcdrm.h
Normal file
548
src/dos/Ntddcdrm.h
Normal file
@ -0,0 +1,548 @@
|
||||
/*++ BUILD Version: 0001 // Increment this if a change has global effects
|
||||
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
Module Name:
|
||||
|
||||
ntddcdrm.h
|
||||
|
||||
Abstract:
|
||||
|
||||
This module contains structures and definitions
|
||||
associated with CDROM IOCTls.
|
||||
|
||||
Author:
|
||||
|
||||
Mike Glass
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
// begin_winioctl
|
||||
|
||||
#ifndef _NTDDCDRM_
|
||||
#define _NTDDCDRM_
|
||||
|
||||
#if _MSC_VER >= 1200
|
||||
#pragma warning(push)
|
||||
#endif
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// remove some level 4 warnings for this header file:
|
||||
#pragma warning(disable:4200) // array[0]
|
||||
#pragma warning(disable:4201) // nameless struct/unions
|
||||
#pragma warning(disable:4214) // bit fields other than int
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//
|
||||
// NtDeviceIoControlFile IoControlCode values for this device.
|
||||
//
|
||||
// Warning: Remember that the low two bits of the code specify how the
|
||||
// buffers are passed to the driver!
|
||||
//
|
||||
|
||||
#define IOCTL_CDROM_BASE FILE_DEVICE_CD_ROM
|
||||
|
||||
#define IOCTL_CDROM_UNLOAD_DRIVER CTL_CODE(IOCTL_CDROM_BASE, 0x0402, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
|
||||
//
|
||||
// CDROM Audio Device Control Functions
|
||||
//
|
||||
|
||||
#define IOCTL_CDROM_READ_TOC CTL_CODE(IOCTL_CDROM_BASE, 0x0000, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_SEEK_AUDIO_MSF CTL_CODE(IOCTL_CDROM_BASE, 0x0001, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_STOP_AUDIO CTL_CODE(IOCTL_CDROM_BASE, 0x0002, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_PAUSE_AUDIO CTL_CODE(IOCTL_CDROM_BASE, 0x0003, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_RESUME_AUDIO CTL_CODE(IOCTL_CDROM_BASE, 0x0004, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_GET_VOLUME CTL_CODE(IOCTL_CDROM_BASE, 0x0005, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_PLAY_AUDIO_MSF CTL_CODE(IOCTL_CDROM_BASE, 0x0006, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_SET_VOLUME CTL_CODE(IOCTL_CDROM_BASE, 0x000A, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_READ_Q_CHANNEL CTL_CODE(IOCTL_CDROM_BASE, 0x000B, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_GET_CONTROL CTL_CODE(IOCTL_CDROM_BASE, 0x000D, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_GET_LAST_SESSION CTL_CODE(IOCTL_CDROM_BASE, 0x000E, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_RAW_READ CTL_CODE(IOCTL_CDROM_BASE, 0x000F, METHOD_OUT_DIRECT, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_DISK_TYPE CTL_CODE(IOCTL_CDROM_BASE, 0x0010, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
#define IOCTL_CDROM_GET_DRIVE_GEOMETRY CTL_CODE(IOCTL_CDROM_BASE, 0x0013, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_GET_DRIVE_GEOMETRY_EX CTL_CODE(IOCTL_CDROM_BASE, 0x0014, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
|
||||
#define IOCTL_CDROM_READ_TOC_EX CTL_CODE(IOCTL_CDROM_BASE, 0x0015, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_GET_CONFIGURATION CTL_CODE(IOCTL_CDROM_BASE, 0x0016, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
|
||||
// end_winioctl
|
||||
|
||||
//
|
||||
// The following device control codes are common for all class drivers. The
|
||||
// functions codes defined here must match all of the other class drivers.
|
||||
//
|
||||
// Warning: these codes will be replaced in the future with the IOCTL_STORAGE
|
||||
// codes included below
|
||||
//
|
||||
|
||||
#define IOCTL_CDROM_CHECK_VERIFY CTL_CODE(IOCTL_CDROM_BASE, 0x0200, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_MEDIA_REMOVAL CTL_CODE(IOCTL_CDROM_BASE, 0x0201, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_EJECT_MEDIA CTL_CODE(IOCTL_CDROM_BASE, 0x0202, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_LOAD_MEDIA CTL_CODE(IOCTL_CDROM_BASE, 0x0203, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_RESERVE CTL_CODE(IOCTL_CDROM_BASE, 0x0204, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_RELEASE CTL_CODE(IOCTL_CDROM_BASE, 0x0205, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_FIND_NEW_DEVICES CTL_CODE(IOCTL_CDROM_BASE, 0x0206, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
|
||||
//
|
||||
// The following file contains the IOCTL_STORAGE class ioctl definitions
|
||||
//
|
||||
|
||||
#include "ntddstor.h"
|
||||
|
||||
// begin_winioctl
|
||||
|
||||
//
|
||||
// The following device control code is for the SIMBAD simulated bad
|
||||
// sector facility. See SIMBAD.H in this directory for related structures.
|
||||
//
|
||||
|
||||
#define IOCTL_CDROM_SIMBAD CTL_CODE(IOCTL_CDROM_BASE, 0x1003, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
|
||||
//
|
||||
// Maximum CD Rom size
|
||||
//
|
||||
|
||||
#define MAXIMUM_NUMBER_TRACKS 100
|
||||
#define MAXIMUM_CDROM_SIZE 804
|
||||
#define MINIMUM_CDROM_READ_TOC_EX_SIZE 2 // two bytes min transferred
|
||||
|
||||
//
|
||||
// READ_TOC_EX structure
|
||||
//
|
||||
typedef struct _CDROM_READ_TOC_EX {
|
||||
UCHAR Format : 4;
|
||||
UCHAR Reserved1 : 3; // future expansion
|
||||
UCHAR Msf : 1;
|
||||
UCHAR SessionTrack;
|
||||
UCHAR Reserved2; // future expansion
|
||||
UCHAR Reserved3; // future expansion
|
||||
} CDROM_READ_TOC_EX, *PCDROM_READ_TOC_EX;
|
||||
|
||||
#define CDROM_READ_TOC_EX_FORMAT_TOC 0x00
|
||||
#define CDROM_READ_TOC_EX_FORMAT_SESSION 0x01
|
||||
#define CDROM_READ_TOC_EX_FORMAT_FULL_TOC 0x02
|
||||
#define CDROM_READ_TOC_EX_FORMAT_PMA 0x03
|
||||
#define CDROM_READ_TOC_EX_FORMAT_ATIP 0x04
|
||||
#define CDROM_READ_TOC_EX_FORMAT_CDTEXT 0x05
|
||||
|
||||
//
|
||||
// CD ROM Table OF Contents (TOC)
|
||||
// Format 0 - Get table of contents
|
||||
//
|
||||
|
||||
typedef struct _TRACK_DATA {
|
||||
UCHAR Reserved;
|
||||
UCHAR Control : 4;
|
||||
UCHAR Adr : 4;
|
||||
UCHAR TrackNumber;
|
||||
UCHAR Reserved1;
|
||||
UCHAR Address[4];
|
||||
} TRACK_DATA, *PTRACK_DATA;
|
||||
|
||||
typedef struct _CDROM_TOC {
|
||||
|
||||
//
|
||||
// Header
|
||||
//
|
||||
|
||||
UCHAR Length[2]; // add two bytes for this field
|
||||
UCHAR FirstTrack;
|
||||
UCHAR LastTrack;
|
||||
|
||||
//
|
||||
// Track data
|
||||
//
|
||||
|
||||
TRACK_DATA TrackData[MAXIMUM_NUMBER_TRACKS];
|
||||
} CDROM_TOC, *PCDROM_TOC;
|
||||
|
||||
#define CDROM_TOC_SIZE sizeof(CDROM_TOC)
|
||||
|
||||
//
|
||||
// CD ROM Table OF Contents
|
||||
// Format 1 - Session Information
|
||||
//
|
||||
|
||||
typedef struct _CDROM_TOC_SESSION_DATA {
|
||||
|
||||
//
|
||||
// Header
|
||||
//
|
||||
|
||||
UCHAR Length[2]; // add two bytes for this field
|
||||
UCHAR FirstCompleteSession;
|
||||
UCHAR LastCompleteSession;
|
||||
|
||||
//
|
||||
// One track, representing the first track
|
||||
// of the last finished session
|
||||
//
|
||||
|
||||
TRACK_DATA TrackData[1];
|
||||
|
||||
} CDROM_TOC_SESSION_DATA, *PCDROM_TOC_SESSION_DATA;
|
||||
|
||||
|
||||
//
|
||||
// CD ROM Table OF Contents
|
||||
// Format 2 - Full TOC
|
||||
//
|
||||
|
||||
typedef struct _CDROM_TOC_FULL_TOC_DATA_BLOCK {
|
||||
UCHAR SessionNumber;
|
||||
UCHAR Control : 4;
|
||||
UCHAR Adr : 4;
|
||||
UCHAR Reserved1;
|
||||
UCHAR Point;
|
||||
UCHAR MsfExtra[3];
|
||||
UCHAR Zero;
|
||||
UCHAR Msf[3];
|
||||
} CDROM_TOC_FULL_TOC_DATA_BLOCK, *PCDROM_TOC_FULL_TOC_DATA_BLOCK;
|
||||
|
||||
typedef struct _CDROM_TOC_FULL_TOC_DATA {
|
||||
|
||||
//
|
||||
// Header
|
||||
//
|
||||
|
||||
UCHAR Length[2]; // add two bytes for this field
|
||||
UCHAR FirstCompleteSession;
|
||||
UCHAR LastCompleteSession;
|
||||
|
||||
//
|
||||
// one to N descriptors included
|
||||
//
|
||||
|
||||
CDROM_TOC_FULL_TOC_DATA_BLOCK Descriptors[0];
|
||||
|
||||
} CDROM_TOC_FULL_TOC_DATA, *PCDROM_TOC_FULL_TOC_DATA;
|
||||
|
||||
//
|
||||
// CD ROM Table OF Contents
|
||||
// Format 3 - Program Memory Area
|
||||
//
|
||||
typedef struct _CDROM_TOC_PMA_DATA {
|
||||
|
||||
//
|
||||
// Header
|
||||
//
|
||||
|
||||
UCHAR Length[2]; // add two bytes for this field
|
||||
UCHAR Reserved1;
|
||||
UCHAR Reserved2;
|
||||
|
||||
//
|
||||
// one to N descriptors included
|
||||
//
|
||||
|
||||
CDROM_TOC_FULL_TOC_DATA_BLOCK Descriptors[0];
|
||||
|
||||
} CDROM_TOC_PMA_DATA, *PCDROM_TOC_PMA_DATA;
|
||||
|
||||
//
|
||||
// CD ROM Table OF Contents
|
||||
// Format 4 - Absolute Time In Pregroove
|
||||
//
|
||||
|
||||
typedef struct _CDROM_TOC_ATIP_DATA_BLOCK {
|
||||
|
||||
UCHAR CdrwReferenceSpeed : 3;
|
||||
UCHAR Reserved3 : 1;
|
||||
UCHAR WritePower : 3;
|
||||
UCHAR True1 : 1;
|
||||
UCHAR Reserved4 : 6;
|
||||
UCHAR UnrestrictedUse : 1;
|
||||
UCHAR Reserved5 : 1;
|
||||
UCHAR A3Valid : 1;
|
||||
UCHAR A2Valid : 1;
|
||||
UCHAR A1Valid : 1;
|
||||
UCHAR DiscSubType : 3;
|
||||
UCHAR IsCdrw : 1;
|
||||
UCHAR True2 : 1;
|
||||
UCHAR Reserved7;
|
||||
|
||||
UCHAR LeadInMsf[3];
|
||||
UCHAR Reserved8;
|
||||
|
||||
UCHAR LeadOutMsf[3];
|
||||
UCHAR Reserved9;
|
||||
|
||||
UCHAR A1Values[3];
|
||||
UCHAR Reserved10;
|
||||
|
||||
UCHAR A2Values[3];
|
||||
UCHAR Reserved11;
|
||||
|
||||
UCHAR A3Values[3];
|
||||
UCHAR Reserved12;
|
||||
|
||||
} CDROM_TOC_ATIP_DATA_BLOCK, *PCDROM_TOC_ATIP_DATA_BLOCK;
|
||||
|
||||
typedef struct _CDROM_TOC_ATIP_DATA {
|
||||
|
||||
//
|
||||
// Header
|
||||
//
|
||||
|
||||
UCHAR Length[2]; // add two bytes for this field
|
||||
UCHAR Reserved1;
|
||||
UCHAR Reserved2;
|
||||
|
||||
//
|
||||
// zero? to N descriptors included.
|
||||
//
|
||||
|
||||
CDROM_TOC_ATIP_DATA_BLOCK Descriptors[0];
|
||||
|
||||
} CDROM_TOC_ATIP_DATA, *PCDROM_TOC_ATIP_DATA;
|
||||
|
||||
//
|
||||
// CD ROM Table OF Contents
|
||||
// Format 5 - CD Text Info
|
||||
//
|
||||
typedef struct _CDROM_TOC_CD_TEXT_DATA_BLOCK {
|
||||
UCHAR PackType;
|
||||
UCHAR TrackNumber : 7;
|
||||
UCHAR ExtensionFlag : 1; // should be zero!
|
||||
UCHAR SequenceNumber;
|
||||
UCHAR CharacterPosition : 4;
|
||||
UCHAR BlockNumber : 3;
|
||||
UCHAR Unicode : 1;
|
||||
union {
|
||||
UCHAR Text[12];
|
||||
WCHAR WText[6];
|
||||
};
|
||||
UCHAR CRC[2];
|
||||
} CDROM_TOC_CD_TEXT_DATA_BLOCK, *PCDROM_TOC_CD_TEXT_DATA_BLOCK;
|
||||
|
||||
typedef struct _CDROM_TOC_CD_TEXT_DATA {
|
||||
|
||||
//
|
||||
// Header
|
||||
//
|
||||
|
||||
UCHAR Length[2]; // add two bytes for this field
|
||||
UCHAR Reserved1;
|
||||
UCHAR Reserved2;
|
||||
|
||||
//
|
||||
// the text info comes in discrete blocks of
|
||||
// a heavily-overloaded structure
|
||||
//
|
||||
|
||||
CDROM_TOC_CD_TEXT_DATA_BLOCK Descriptors[0];
|
||||
|
||||
} CDROM_TOC_CD_TEXT_DATA, *PCDROM_TOC_CD_TEXT_DATA;
|
||||
|
||||
//
|
||||
// These are the types used for PackType field in CDROM_TOC_CD_TEXT_DATA_BLOCK
|
||||
// and also for requesting specific info from IOCTL_CDROM_READ_CD_TEXT
|
||||
//
|
||||
#define CDROM_CD_TEXT_PACK_ALBUM_NAME 0x80
|
||||
#define CDROM_CD_TEXT_PACK_PERFORMER 0x81
|
||||
#define CDROM_CD_TEXT_PACK_SONGWRITER 0x82
|
||||
#define CDROM_CD_TEXT_PACK_COMPOSER 0x83
|
||||
#define CDROM_CD_TEXT_PACK_ARRANGER 0x84
|
||||
#define CDROM_CD_TEXT_PACK_MESSAGES 0x85
|
||||
#define CDROM_CD_TEXT_PACK_DISC_ID 0x86
|
||||
#define CDROM_CD_TEXT_PACK_GENRE 0x87
|
||||
#define CDROM_CD_TEXT_PACK_TOC_INFO 0x88
|
||||
#define CDROM_CD_TEXT_PACK_TOC_INFO2 0x89
|
||||
// 0x8a - 0x8d are reserved....
|
||||
#define CDROM_CD_TEXT_PACK_UPC_EAN 0x8e
|
||||
#define CDROM_CD_TEXT_PACK_SIZE_INFO 0x8f
|
||||
|
||||
//
|
||||
// Play audio starting at MSF and ending at MSF
|
||||
//
|
||||
|
||||
typedef struct _CDROM_PLAY_AUDIO_MSF {
|
||||
UCHAR StartingM;
|
||||
UCHAR StartingS;
|
||||
UCHAR StartingF;
|
||||
UCHAR EndingM;
|
||||
UCHAR EndingS;
|
||||
UCHAR EndingF;
|
||||
} CDROM_PLAY_AUDIO_MSF, *PCDROM_PLAY_AUDIO_MSF;
|
||||
|
||||
//
|
||||
// Seek to MSF
|
||||
//
|
||||
|
||||
typedef struct _CDROM_SEEK_AUDIO_MSF {
|
||||
UCHAR M;
|
||||
UCHAR S;
|
||||
UCHAR F;
|
||||
} CDROM_SEEK_AUDIO_MSF, *PCDROM_SEEK_AUDIO_MSF;
|
||||
|
||||
|
||||
//
|
||||
// Flags for the disk type
|
||||
//
|
||||
|
||||
typedef struct _CDROM_DISK_DATA {
|
||||
|
||||
ULONG DiskData;
|
||||
|
||||
} CDROM_DISK_DATA, *PCDROM_DISK_DATA;
|
||||
|
||||
#define CDROM_DISK_AUDIO_TRACK (0x00000001)
|
||||
#define CDROM_DISK_DATA_TRACK (0x00000002)
|
||||
|
||||
//
|
||||
// CD ROM Data Mode Codes, used with IOCTL_CDROM_READ_Q_CHANNEL
|
||||
//
|
||||
|
||||
#define IOCTL_CDROM_SUB_Q_CHANNEL 0x00
|
||||
#define IOCTL_CDROM_CURRENT_POSITION 0x01
|
||||
#define IOCTL_CDROM_MEDIA_CATALOG 0x02
|
||||
#define IOCTL_CDROM_TRACK_ISRC 0x03
|
||||
|
||||
typedef struct _CDROM_SUB_Q_DATA_FORMAT {
|
||||
UCHAR Format;
|
||||
UCHAR Track;
|
||||
} CDROM_SUB_Q_DATA_FORMAT, *PCDROM_SUB_Q_DATA_FORMAT;
|
||||
|
||||
|
||||
//
|
||||
// CD ROM Sub-Q Channel Data Format
|
||||
//
|
||||
|
||||
typedef struct _SUB_Q_HEADER {
|
||||
UCHAR Reserved;
|
||||
UCHAR AudioStatus;
|
||||
UCHAR DataLength[2];
|
||||
} SUB_Q_HEADER, *PSUB_Q_HEADER;
|
||||
|
||||
typedef struct _SUB_Q_CURRENT_POSITION {
|
||||
SUB_Q_HEADER Header;
|
||||
UCHAR FormatCode;
|
||||
UCHAR Control : 4;
|
||||
UCHAR ADR : 4;
|
||||
UCHAR TrackNumber;
|
||||
UCHAR IndexNumber;
|
||||
UCHAR AbsoluteAddress[4];
|
||||
UCHAR TrackRelativeAddress[4];
|
||||
} SUB_Q_CURRENT_POSITION, *PSUB_Q_CURRENT_POSITION;
|
||||
|
||||
typedef struct _SUB_Q_MEDIA_CATALOG_NUMBER {
|
||||
SUB_Q_HEADER Header;
|
||||
UCHAR FormatCode;
|
||||
UCHAR Reserved[3];
|
||||
UCHAR Reserved1 : 7;
|
||||
UCHAR Mcval : 1;
|
||||
UCHAR MediaCatalog[15];
|
||||
} SUB_Q_MEDIA_CATALOG_NUMBER, *PSUB_Q_MEDIA_CATALOG_NUMBER;
|
||||
|
||||
typedef struct _SUB_Q_TRACK_ISRC {
|
||||
SUB_Q_HEADER Header;
|
||||
UCHAR FormatCode;
|
||||
UCHAR Reserved0;
|
||||
UCHAR Track;
|
||||
UCHAR Reserved1;
|
||||
UCHAR Reserved2 : 7;
|
||||
UCHAR Tcval : 1;
|
||||
UCHAR TrackIsrc[15];
|
||||
} SUB_Q_TRACK_ISRC, *PSUB_Q_TRACK_ISRC;
|
||||
|
||||
typedef union _SUB_Q_CHANNEL_DATA {
|
||||
SUB_Q_CURRENT_POSITION CurrentPosition;
|
||||
SUB_Q_MEDIA_CATALOG_NUMBER MediaCatalog;
|
||||
SUB_Q_TRACK_ISRC TrackIsrc;
|
||||
} SUB_Q_CHANNEL_DATA, *PSUB_Q_CHANNEL_DATA;
|
||||
|
||||
//
|
||||
// Audio Status Codes
|
||||
//
|
||||
|
||||
#define AUDIO_STATUS_NOT_SUPPORTED 0x00
|
||||
#define AUDIO_STATUS_IN_PROGRESS 0x11
|
||||
#define AUDIO_STATUS_PAUSED 0x12
|
||||
#define AUDIO_STATUS_PLAY_COMPLETE 0x13
|
||||
#define AUDIO_STATUS_PLAY_ERROR 0x14
|
||||
#define AUDIO_STATUS_NO_STATUS 0x15
|
||||
|
||||
//
|
||||
// ADR Sub-channel Q Field
|
||||
//
|
||||
|
||||
#define ADR_NO_MODE_INFORMATION 0x0
|
||||
#define ADR_ENCODES_CURRENT_POSITION 0x1
|
||||
#define ADR_ENCODES_MEDIA_CATALOG 0x2
|
||||
#define ADR_ENCODES_ISRC 0x3
|
||||
|
||||
//
|
||||
// Sub-channel Q Control Bits
|
||||
//
|
||||
|
||||
#define AUDIO_WITH_PREEMPHASIS 0x1
|
||||
#define DIGITAL_COPY_PERMITTED 0x2
|
||||
#define AUDIO_DATA_TRACK 0x4
|
||||
#define TWO_FOUR_CHANNEL_AUDIO 0x8
|
||||
|
||||
//
|
||||
// Get Audio control parameters
|
||||
//
|
||||
|
||||
typedef struct _CDROM_AUDIO_CONTROL {
|
||||
UCHAR LbaFormat;
|
||||
USHORT LogicalBlocksPerSecond;
|
||||
} CDROM_AUDIO_CONTROL, *PCDROM_AUDIO_CONTROL;
|
||||
|
||||
//
|
||||
// Volume control - Volume takes a value between 1 and 0xFF.
|
||||
// SCSI-II CDROM audio suppports up to 4 audio ports with
|
||||
// Independent volume control.
|
||||
//
|
||||
|
||||
typedef struct _VOLUME_CONTROL {
|
||||
UCHAR PortVolume[4];
|
||||
} VOLUME_CONTROL, *PVOLUME_CONTROL;
|
||||
|
||||
typedef enum _TRACK_MODE_TYPE {
|
||||
YellowMode2,
|
||||
XAForm2,
|
||||
CDDA
|
||||
} TRACK_MODE_TYPE, *PTRACK_MODE_TYPE;
|
||||
|
||||
//
|
||||
// Passed to cdrom to describe the raw read, ie. Mode 2, Form 2, CDDA...
|
||||
//
|
||||
|
||||
typedef struct __RAW_READ_INFO {
|
||||
LARGE_INTEGER DiskOffset;
|
||||
ULONG SectorCount;
|
||||
TRACK_MODE_TYPE TrackMode;
|
||||
} RAW_READ_INFO, *PRAW_READ_INFO;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if _MSC_VER >= 1200
|
||||
#pragma warning(pop) // un-sets any local warning changes
|
||||
#else
|
||||
#pragma warning(default:4200) // array[0] is not a warning for this file
|
||||
#pragma warning(default:4201) // nameless struct/unions
|
||||
#pragma warning(default:4214) // bit fields other than int
|
||||
#endif
|
||||
|
||||
|
||||
#endif // _NTDDCDRM_
|
||||
|
||||
// end_winioctl
|
||||
|
||||
|
313
src/dos/Ntddscsi.h
Normal file
313
src/dos/Ntddscsi.h
Normal file
@ -0,0 +1,313 @@
|
||||
/*++ BUILD Version: 0001 // Increment this if a change has global effects
|
||||
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
Module Name:
|
||||
|
||||
ntddscsi.h
|
||||
|
||||
Abstract:
|
||||
|
||||
This is the include file that defines all constants and types for
|
||||
accessing the SCSI port adapters.
|
||||
|
||||
Author:
|
||||
|
||||
Jeff Havens
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
//
|
||||
// Interface GUIDs
|
||||
//
|
||||
// need these GUIDs outside conditional includes so that user can
|
||||
// #include <ntddscsi.h> in precompiled header
|
||||
// #include <initguid.h> in a single source file
|
||||
// #include <ntddscsi.h> in that source file a second time to instantiate the GUIDs
|
||||
//
|
||||
#ifdef DEFINE_GUID
|
||||
//
|
||||
// Make sure FAR is defined...
|
||||
//
|
||||
#ifndef FAR
|
||||
#ifdef _WIN32
|
||||
#define FAR
|
||||
#else
|
||||
#define FAR _far
|
||||
#endif
|
||||
#endif
|
||||
|
||||
DEFINE_GUID(ScsiRawInterfaceGuid, 0x53f56309L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);
|
||||
DEFINE_GUID(WmiScsiAddressGuid, 0x53f5630fL, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);
|
||||
#endif
|
||||
|
||||
#ifndef _NTDDSCSIH_
|
||||
#define _NTDDSCSIH_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//
|
||||
// Device Name - this string is the name of the device. It is the name
|
||||
// that should be passed to NtOpenFile when accessing the device.
|
||||
//
|
||||
// Note: For devices that support multiple units, it should be suffixed
|
||||
// with the Ascii representation of the unit number.
|
||||
//
|
||||
|
||||
#define IOCTL_SCSI_BASE FILE_DEVICE_CONTROLLER
|
||||
|
||||
#define DD_SCSI_DEVICE_NAME "\\Device\\ScsiPort"
|
||||
|
||||
|
||||
//
|
||||
// NtDeviceIoControlFile IoControlCode values for this device.
|
||||
//
|
||||
// Warning: Remember that the low two bits of the code specify how the
|
||||
// buffers are passed to the driver!
|
||||
//
|
||||
|
||||
#define IOCTL_SCSI_PASS_THROUGH CTL_CODE(IOCTL_SCSI_BASE, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
|
||||
#define IOCTL_SCSI_MINIPORT CTL_CODE(IOCTL_SCSI_BASE, 0x0402, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
|
||||
#define IOCTL_SCSI_GET_INQUIRY_DATA CTL_CODE(IOCTL_SCSI_BASE, 0x0403, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_SCSI_GET_CAPABILITIES CTL_CODE(IOCTL_SCSI_BASE, 0x0404, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_SCSI_PASS_THROUGH_DIRECT CTL_CODE(IOCTL_SCSI_BASE, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
|
||||
#define IOCTL_SCSI_GET_ADDRESS CTL_CODE(IOCTL_SCSI_BASE, 0x0406, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_SCSI_RESCAN_BUS CTL_CODE(IOCTL_SCSI_BASE, 0x0407, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_SCSI_GET_DUMP_POINTERS CTL_CODE(IOCTL_SCSI_BASE, 0x0408, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_SCSI_FREE_DUMP_POINTERS CTL_CODE(IOCTL_SCSI_BASE, 0x0409, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_IDE_PASS_THROUGH CTL_CODE(IOCTL_SCSI_BASE, 0x040a, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
|
||||
|
||||
//
|
||||
// Define the SCSI pass through structure.
|
||||
//
|
||||
|
||||
typedef struct _SCSI_PASS_THROUGH {
|
||||
USHORT Length;
|
||||
UCHAR ScsiStatus;
|
||||
UCHAR PathId;
|
||||
UCHAR TargetId;
|
||||
UCHAR Lun;
|
||||
UCHAR CdbLength;
|
||||
UCHAR SenseInfoLength;
|
||||
UCHAR DataIn;
|
||||
ULONG DataTransferLength;
|
||||
ULONG TimeOutValue;
|
||||
ULONG DataBufferOffset; //ULONG_PTR DataBufferOffset;
|
||||
ULONG SenseInfoOffset;
|
||||
UCHAR Cdb[16];
|
||||
}SCSI_PASS_THROUGH, *PSCSI_PASS_THROUGH;
|
||||
|
||||
//
|
||||
// Define the SCSI pass through direct structure.
|
||||
//
|
||||
|
||||
typedef struct _SCSI_PASS_THROUGH_DIRECT {
|
||||
USHORT Length;
|
||||
UCHAR ScsiStatus;
|
||||
UCHAR PathId;
|
||||
UCHAR TargetId;
|
||||
UCHAR Lun;
|
||||
UCHAR CdbLength;
|
||||
UCHAR SenseInfoLength;
|
||||
UCHAR DataIn;
|
||||
ULONG DataTransferLength;
|
||||
ULONG TimeOutValue;
|
||||
PVOID DataBuffer;
|
||||
ULONG SenseInfoOffset;
|
||||
UCHAR Cdb[16];
|
||||
}SCSI_PASS_THROUGH_DIRECT, *PSCSI_PASS_THROUGH_DIRECT;
|
||||
|
||||
|
||||
//
|
||||
// Define the SCSI pass through direct structure for Win64 (thunking).
|
||||
//
|
||||
#if defined(_WIN64)
|
||||
typedef struct _SCSI_PASS_THROUGH32 {
|
||||
USHORT Length;
|
||||
UCHAR ScsiStatus;
|
||||
UCHAR PathId;
|
||||
UCHAR TargetId;
|
||||
UCHAR Lun;
|
||||
UCHAR CdbLength;
|
||||
UCHAR SenseInfoLength;
|
||||
UCHAR DataIn;
|
||||
ULONG DataTransferLength;
|
||||
ULONG TimeOutValue;
|
||||
ULONG32 DataBufferOffset;
|
||||
ULONG SenseInfoOffset;
|
||||
UCHAR Cdb[16];
|
||||
}SCSI_PASS_THROUGH32, *PSCSI_PASS_THROUGH32;
|
||||
|
||||
//
|
||||
// Define the SCSI pass through direct structure.
|
||||
//
|
||||
|
||||
typedef struct _SCSI_PASS_THROUGH_DIRECT32 {
|
||||
USHORT Length;
|
||||
UCHAR ScsiStatus;
|
||||
UCHAR PathId;
|
||||
UCHAR TargetId;
|
||||
UCHAR Lun;
|
||||
UCHAR CdbLength;
|
||||
UCHAR SenseInfoLength;
|
||||
UCHAR DataIn;
|
||||
ULONG DataTransferLength;
|
||||
ULONG TimeOutValue;
|
||||
VOID * POINTER_32 DataBuffer;
|
||||
ULONG SenseInfoOffset;
|
||||
UCHAR Cdb[16];
|
||||
}SCSI_PASS_THROUGH_DIRECT32, *PSCSI_PASS_THROUGH_DIRECT32;
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// Define SCSI information.
|
||||
// Used with the IOCTL_SCSI_GET_INQUIRY_DATA IOCTL.
|
||||
//
|
||||
|
||||
typedef struct _SCSI_BUS_DATA {
|
||||
UCHAR NumberOfLogicalUnits;
|
||||
UCHAR InitiatorBusId;
|
||||
ULONG InquiryDataOffset;
|
||||
}SCSI_BUS_DATA, *PSCSI_BUS_DATA;
|
||||
|
||||
//
|
||||
// Define SCSI adapter bus information structure..
|
||||
// Used with the IOCTL_SCSI_GET_INQUIRY_DATA IOCTL.
|
||||
//
|
||||
|
||||
typedef struct _SCSI_ADAPTER_BUS_INFO {
|
||||
UCHAR NumberOfBuses;
|
||||
SCSI_BUS_DATA BusData[1];
|
||||
} SCSI_ADAPTER_BUS_INFO, *PSCSI_ADAPTER_BUS_INFO;
|
||||
|
||||
//
|
||||
// Define SCSI adapter bus information.
|
||||
// Used with the IOCTL_SCSI_GET_INQUIRY_DATA IOCTL.
|
||||
//
|
||||
|
||||
typedef struct _SCSI_INQUIRY_DATA {
|
||||
UCHAR PathId;
|
||||
UCHAR TargetId;
|
||||
UCHAR Lun;
|
||||
BOOLEAN DeviceClaimed;
|
||||
ULONG InquiryDataLength;
|
||||
ULONG NextInquiryDataOffset;
|
||||
UCHAR InquiryData[1];
|
||||
}SCSI_INQUIRY_DATA, *PSCSI_INQUIRY_DATA;
|
||||
|
||||
//
|
||||
// Define header for I/O control SRB.
|
||||
//
|
||||
|
||||
typedef struct _SRB_IO_CONTROL {
|
||||
ULONG HeaderLength;
|
||||
UCHAR Signature[8];
|
||||
ULONG Timeout;
|
||||
ULONG ControlCode;
|
||||
ULONG ReturnCode;
|
||||
ULONG Length;
|
||||
} SRB_IO_CONTROL, *PSRB_IO_CONTROL;
|
||||
|
||||
//
|
||||
// SCSI port driver capabilities structure.
|
||||
//
|
||||
|
||||
typedef struct _IO_SCSI_CAPABILITIES {
|
||||
|
||||
//
|
||||
// Length of this structure
|
||||
//
|
||||
|
||||
ULONG Length;
|
||||
|
||||
//
|
||||
// Maximum transfer size in single SRB
|
||||
//
|
||||
|
||||
ULONG MaximumTransferLength;
|
||||
|
||||
//
|
||||
// Maximum number of physical pages per data buffer
|
||||
//
|
||||
|
||||
ULONG MaximumPhysicalPages;
|
||||
|
||||
//
|
||||
// Async calls from port to class
|
||||
//
|
||||
|
||||
ULONG SupportedAsynchronousEvents;
|
||||
|
||||
//
|
||||
// Alignment mask for data transfers.
|
||||
//
|
||||
|
||||
ULONG AlignmentMask;
|
||||
|
||||
//
|
||||
// Supports tagged queuing
|
||||
//
|
||||
|
||||
BOOLEAN TaggedQueuing;
|
||||
|
||||
//
|
||||
// Host adapter scans down for bios devices.
|
||||
//
|
||||
|
||||
BOOLEAN AdapterScansDown;
|
||||
|
||||
//
|
||||
// The host adapter uses programmed I/O.
|
||||
//
|
||||
|
||||
BOOLEAN AdapterUsesPio;
|
||||
|
||||
} IO_SCSI_CAPABILITIES, *PIO_SCSI_CAPABILITIES;
|
||||
|
||||
typedef struct _SCSI_ADDRESS {
|
||||
ULONG Length;
|
||||
UCHAR PortNumber;
|
||||
UCHAR PathId;
|
||||
UCHAR TargetId;
|
||||
UCHAR Lun;
|
||||
}SCSI_ADDRESS, *PSCSI_ADDRESS;
|
||||
|
||||
//
|
||||
// Define structure for returning crash dump pointers.
|
||||
//
|
||||
|
||||
struct _ADAPTER_OBJECT;
|
||||
|
||||
typedef struct _DUMP_POINTERS {
|
||||
struct _ADAPTER_OBJECT *AdapterObject;
|
||||
PVOID MappedRegisterBase;
|
||||
PVOID DumpData;
|
||||
PVOID CommonBufferVa;
|
||||
LARGE_INTEGER CommonBufferPa;
|
||||
ULONG CommonBufferSize;
|
||||
BOOLEAN AllocateCommonBuffers;
|
||||
BOOLEAN UseDiskDump;
|
||||
UCHAR Spare1[2];
|
||||
PVOID DeviceObject;
|
||||
} DUMP_POINTERS, *PDUMP_POINTERS;
|
||||
|
||||
//
|
||||
// Define values for pass-through DataIn field.
|
||||
//
|
||||
|
||||
#define SCSI_IOCTL_DATA_OUT 0
|
||||
#define SCSI_IOCTL_DATA_IN 1
|
||||
#define SCSI_IOCTL_DATA_UNSPECIFIED 2
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
746
src/dos/Ntddstor.h
Normal file
746
src/dos/Ntddstor.h
Normal file
@ -0,0 +1,746 @@
|
||||
/*++ BUILD Version: 0001 // Increment this if a change has global effects
|
||||
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
|
||||
Module Name:
|
||||
|
||||
ntddstor.h
|
||||
|
||||
Abstract:
|
||||
|
||||
This is the include file that defines all common constants and types
|
||||
accessing the storage class drivers
|
||||
|
||||
Author:
|
||||
|
||||
Peter Wieland 19-Jun-1996
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
|
||||
//
|
||||
// Interface GUIDs
|
||||
//
|
||||
// need these GUIDs outside conditional includes so that user can
|
||||
// #include <ntddstor.h> in precompiled header
|
||||
// #include <initguid.h> in a single source file
|
||||
// #include <ntddstor.h> in that source file a second time to instantiate the GUIDs
|
||||
//
|
||||
#ifdef DEFINE_GUID
|
||||
//
|
||||
// Make sure FAR is defined...
|
||||
//
|
||||
#ifndef FAR
|
||||
#ifdef _WIN32
|
||||
#define FAR
|
||||
#else
|
||||
#define FAR _far
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// begin_wioctlguids
|
||||
DEFINE_GUID(GUID_DEVINTERFACE_DISK, 0x53f56307L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);
|
||||
DEFINE_GUID(GUID_DEVINTERFACE_CDROM, 0x53f56308L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);
|
||||
DEFINE_GUID(GUID_DEVINTERFACE_PARTITION, 0x53f5630aL, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);
|
||||
DEFINE_GUID(GUID_DEVINTERFACE_TAPE, 0x53f5630bL, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);
|
||||
DEFINE_GUID(GUID_DEVINTERFACE_WRITEONCEDISK, 0x53f5630cL, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);
|
||||
DEFINE_GUID(GUID_DEVINTERFACE_VOLUME, 0x53f5630dL, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);
|
||||
DEFINE_GUID(GUID_DEVINTERFACE_MEDIUMCHANGER, 0x53f56310L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);
|
||||
DEFINE_GUID(GUID_DEVINTERFACE_FLOPPY, 0x53f56311L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);
|
||||
DEFINE_GUID(GUID_DEVINTERFACE_CDCHANGER, 0x53f56312L, 0xb6bf, 0x11d0, 0x94, 0xf2, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);
|
||||
DEFINE_GUID(GUID_DEVINTERFACE_STORAGEPORT, 0x2accfe60L, 0xc130, 0x11d2, 0xb0, 0x82, 0x00, 0xa0, 0xc9, 0x1e, 0xfb, 0x8b);
|
||||
// end_wioctlguids
|
||||
|
||||
// begin_wioctlobsoleteguids
|
||||
#define DiskClassGuid GUID_DEVINTERFACE_DISK
|
||||
#define CdRomClassGuid GUID_DEVINTERFACE_CDROM
|
||||
#define PartitionClassGuid GUID_DEVINTERFACE_PARTITION
|
||||
#define TapeClassGuid GUID_DEVINTERFACE_TAPE
|
||||
#define WriteOnceDiskClassGuid GUID_DEVINTERFACE_WRITEONCEDISK
|
||||
#define VolumeClassGuid GUID_DEVINTERFACE_VOLUME
|
||||
#define MediumChangerClassGuid GUID_DEVINTERFACE_MEDIUMCHANGER
|
||||
#define FloppyClassGuid GUID_DEVINTERFACE_FLOPPY
|
||||
#define CdChangerClassGuid GUID_DEVINTERFACE_CDCHANGER
|
||||
#define StoragePortClassGuid GUID_DEVINTERFACE_STORAGEPORT
|
||||
// end_wioctlobsoleteguids
|
||||
#endif
|
||||
|
||||
// begin_winioctl
|
||||
|
||||
#ifndef _NTDDSTOR_H_
|
||||
#define _NTDDSTOR_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//
|
||||
// IoControlCode values for storage devices
|
||||
//
|
||||
|
||||
#define IOCTL_STORAGE_BASE FILE_DEVICE_MASS_STORAGE
|
||||
|
||||
//
|
||||
// The following device control codes are common for all class drivers. They
|
||||
// should be used in place of the older IOCTL_DISK, IOCTL_CDROM and IOCTL_TAPE
|
||||
// common codes
|
||||
//
|
||||
|
||||
#define IOCTL_STORAGE_CHECK_VERIFY CTL_CODE(IOCTL_STORAGE_BASE, 0x0200, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_STORAGE_CHECK_VERIFY2 CTL_CODE(IOCTL_STORAGE_BASE, 0x0200, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_STORAGE_MEDIA_REMOVAL CTL_CODE(IOCTL_STORAGE_BASE, 0x0201, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_STORAGE_EJECT_MEDIA CTL_CODE(IOCTL_STORAGE_BASE, 0x0202, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_STORAGE_LOAD_MEDIA CTL_CODE(IOCTL_STORAGE_BASE, 0x0203, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_STORAGE_LOAD_MEDIA2 CTL_CODE(IOCTL_STORAGE_BASE, 0x0203, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_STORAGE_RESERVE CTL_CODE(IOCTL_STORAGE_BASE, 0x0204, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_STORAGE_RELEASE CTL_CODE(IOCTL_STORAGE_BASE, 0x0205, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_STORAGE_FIND_NEW_DEVICES CTL_CODE(IOCTL_STORAGE_BASE, 0x0206, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
|
||||
#define IOCTL_STORAGE_EJECTION_CONTROL CTL_CODE(IOCTL_STORAGE_BASE, 0x0250, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_STORAGE_MCN_CONTROL CTL_CODE(IOCTL_STORAGE_BASE, 0x0251, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
#define IOCTL_STORAGE_GET_MEDIA_TYPES CTL_CODE(IOCTL_STORAGE_BASE, 0x0300, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_STORAGE_GET_MEDIA_TYPES_EX CTL_CODE(IOCTL_STORAGE_BASE, 0x0301, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_STORAGE_GET_MEDIA_SERIAL_NUMBER CTL_CODE(IOCTL_STORAGE_BASE, 0x0304, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_STORAGE_GET_HOTPLUG_INFO CTL_CODE(IOCTL_STORAGE_BASE, 0x0305, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_STORAGE_SET_HOTPLUG_INFO CTL_CODE(IOCTL_STORAGE_BASE, 0x0306, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
|
||||
|
||||
#define IOCTL_STORAGE_RESET_BUS CTL_CODE(IOCTL_STORAGE_BASE, 0x0400, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_STORAGE_RESET_DEVICE CTL_CODE(IOCTL_STORAGE_BASE, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_STORAGE_BREAK_RESERVATION CTL_CODE(IOCTL_STORAGE_BASE, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
|
||||
#define IOCTL_STORAGE_GET_DEVICE_NUMBER CTL_CODE(IOCTL_STORAGE_BASE, 0x0420, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_STORAGE_PREDICT_FAILURE CTL_CODE(IOCTL_STORAGE_BASE, 0x0440, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
// end_winioctl
|
||||
|
||||
|
||||
#define IOCTL_STORAGE_QUERY_PROPERTY CTL_CODE(IOCTL_STORAGE_BASE, 0x0500, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
|
||||
|
||||
// begin_winioctl
|
||||
|
||||
//
|
||||
// These ioctl codes are obsolete. They are defined here to avoid resuing them
|
||||
// and to allow class drivers to respond to them more easily.
|
||||
//
|
||||
|
||||
#define OBSOLETE_IOCTL_STORAGE_RESET_BUS CTL_CODE(IOCTL_STORAGE_BASE, 0x0400, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
|
||||
#define OBSOLETE_IOCTL_STORAGE_RESET_DEVICE CTL_CODE(IOCTL_STORAGE_BASE, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
|
||||
|
||||
|
||||
//
|
||||
// IOCTL_STORAGE_GET_HOTPLUG_INFO
|
||||
//
|
||||
|
||||
typedef struct _STORAGE_HOTPLUG_INFO {
|
||||
ULONG Size; // version
|
||||
BOOLEAN MediaRemovable; // ie. zip, jaz, cdrom, mo, etc. vs hdd
|
||||
BOOLEAN MediaHotplug; // ie. does the device succeed a lock even though its not lockable media?
|
||||
BOOLEAN DeviceHotplug; // ie. 1394, USB, etc.
|
||||
BOOLEAN WriteCacheEnableOverride; // This field should not be relied upon because it is no longer used
|
||||
} STORAGE_HOTPLUG_INFO, *PSTORAGE_HOTPLUG_INFO;
|
||||
|
||||
//
|
||||
// IOCTL_STORAGE_GET_DEVICE_NUMBER
|
||||
//
|
||||
// input - none
|
||||
//
|
||||
// output - STORAGE_DEVICE_NUMBER structure
|
||||
// The values in the STORAGE_DEVICE_NUMBER structure are guaranteed
|
||||
// to remain unchanged until the system is rebooted. They are not
|
||||
// guaranteed to be persistant across boots.
|
||||
//
|
||||
|
||||
typedef struct _STORAGE_DEVICE_NUMBER {
|
||||
|
||||
//
|
||||
// The FILE_DEVICE_XXX type for this device.
|
||||
//
|
||||
|
||||
DEVICE_TYPE DeviceType;
|
||||
|
||||
//
|
||||
// The number of this device
|
||||
//
|
||||
|
||||
ULONG DeviceNumber;
|
||||
|
||||
//
|
||||
// If the device is partitionable, the partition number of the device.
|
||||
// Otherwise -1
|
||||
//
|
||||
|
||||
ULONG PartitionNumber;
|
||||
} STORAGE_DEVICE_NUMBER, *PSTORAGE_DEVICE_NUMBER;
|
||||
|
||||
//
|
||||
// Define the structures for scsi resets
|
||||
//
|
||||
|
||||
typedef struct _STORAGE_BUS_RESET_REQUEST {
|
||||
UCHAR PathId;
|
||||
} STORAGE_BUS_RESET_REQUEST, *PSTORAGE_BUS_RESET_REQUEST;
|
||||
|
||||
//
|
||||
// IOCTL_STORAGE_MEDIA_REMOVAL disables the mechanism
|
||||
// on a storage device that ejects media. This function
|
||||
// may or may not be supported on storage devices that
|
||||
// support removable media.
|
||||
//
|
||||
// TRUE means prevent media from being removed.
|
||||
// FALSE means allow media removal.
|
||||
//
|
||||
#if defined (_MSC_VER) /* MS Visual C++ */
|
||||
typedef struct _PREVENT_MEDIA_REMOVAL {
|
||||
BOOLEAN PreventMediaRemoval;
|
||||
} PREVENT_MEDIA_REMOVAL, *PPREVENT_MEDIA_REMOVAL;
|
||||
#endif
|
||||
|
||||
// begin_ntminitape
|
||||
|
||||
|
||||
typedef struct _TAPE_STATISTICS {
|
||||
ULONG Version;
|
||||
ULONG Flags;
|
||||
LARGE_INTEGER RecoveredWrites;
|
||||
LARGE_INTEGER UnrecoveredWrites;
|
||||
LARGE_INTEGER RecoveredReads;
|
||||
LARGE_INTEGER UnrecoveredReads;
|
||||
UCHAR CompressionRatioReads;
|
||||
UCHAR CompressionRatioWrites;
|
||||
} TAPE_STATISTICS, *PTAPE_STATISTICS;
|
||||
|
||||
#define RECOVERED_WRITES_VALID 0x00000001
|
||||
#define UNRECOVERED_WRITES_VALID 0x00000002
|
||||
#define RECOVERED_READS_VALID 0x00000004
|
||||
#define UNRECOVERED_READS_VALID 0x00000008
|
||||
#define WRITE_COMPRESSION_INFO_VALID 0x00000010
|
||||
#define READ_COMPRESSION_INFO_VALID 0x00000020
|
||||
|
||||
typedef struct _TAPE_GET_STATISTICS {
|
||||
ULONG Operation;
|
||||
} TAPE_GET_STATISTICS, *PTAPE_GET_STATISTICS;
|
||||
|
||||
#define TAPE_RETURN_STATISTICS 0L
|
||||
#define TAPE_RETURN_ENV_INFO 1L
|
||||
#define TAPE_RESET_STATISTICS 2L
|
||||
|
||||
//
|
||||
// IOCTL_STORAGE_GET_MEDIA_TYPES_EX will return an array of DEVICE_MEDIA_INFO
|
||||
// structures, one per supported type, embedded in the GET_MEDIA_TYPES struct.
|
||||
//
|
||||
|
||||
typedef enum _STORAGE_MEDIA_TYPE {
|
||||
//
|
||||
// Following are defined in ntdddisk.h in the MEDIA_TYPE enum
|
||||
//
|
||||
// Unknown, // Format is unknown
|
||||
// F5_1Pt2_512, // 5.25", 1.2MB, 512 bytes/sector
|
||||
// F3_1Pt44_512, // 3.5", 1.44MB, 512 bytes/sector
|
||||
// F3_2Pt88_512, // 3.5", 2.88MB, 512 bytes/sector
|
||||
// F3_20Pt8_512, // 3.5", 20.8MB, 512 bytes/sector
|
||||
// F3_720_512, // 3.5", 720KB, 512 bytes/sector
|
||||
// F5_360_512, // 5.25", 360KB, 512 bytes/sector
|
||||
// F5_320_512, // 5.25", 320KB, 512 bytes/sector
|
||||
// F5_320_1024, // 5.25", 320KB, 1024 bytes/sector
|
||||
// F5_180_512, // 5.25", 180KB, 512 bytes/sector
|
||||
// F5_160_512, // 5.25", 160KB, 512 bytes/sector
|
||||
// RemovableMedia, // Removable media other than floppy
|
||||
// FixedMedia, // Fixed hard disk media
|
||||
// F3_120M_512, // 3.5", 120M Floppy
|
||||
// F3_640_512, // 3.5" , 640KB, 512 bytes/sector
|
||||
// F5_640_512, // 5.25", 640KB, 512 bytes/sector
|
||||
// F5_720_512, // 5.25", 720KB, 512 bytes/sector
|
||||
// F3_1Pt2_512, // 3.5" , 1.2Mb, 512 bytes/sector
|
||||
// F3_1Pt23_1024, // 3.5" , 1.23Mb, 1024 bytes/sector
|
||||
// F5_1Pt23_1024, // 5.25", 1.23MB, 1024 bytes/sector
|
||||
// F3_128Mb_512, // 3.5" MO 128Mb 512 bytes/sector
|
||||
// F3_230Mb_512, // 3.5" MO 230Mb 512 bytes/sector
|
||||
// F8_256_128, // 8", 256KB, 128 bytes/sector
|
||||
// F3_200Mb_512, // 3.5", 200M Floppy (HiFD)
|
||||
//
|
||||
|
||||
DDS_4mm = 0x20, // Tape - DAT DDS1,2,... (all vendors)
|
||||
MiniQic, // Tape - miniQIC Tape
|
||||
Travan, // Tape - Travan TR-1,2,3,...
|
||||
QIC, // Tape - QIC
|
||||
MP_8mm, // Tape - 8mm Exabyte Metal Particle
|
||||
AME_8mm, // Tape - 8mm Exabyte Advanced Metal Evap
|
||||
AIT1_8mm, // Tape - 8mm Sony AIT
|
||||
DLT, // Tape - DLT Compact IIIxt, IV
|
||||
NCTP, // Tape - Philips NCTP
|
||||
IBM_3480, // Tape - IBM 3480
|
||||
IBM_3490E, // Tape - IBM 3490E
|
||||
IBM_Magstar_3590, // Tape - IBM Magstar 3590
|
||||
IBM_Magstar_MP, // Tape - IBM Magstar MP
|
||||
STK_DATA_D3, // Tape - STK Data D3
|
||||
SONY_DTF, // Tape - Sony DTF
|
||||
DV_6mm, // Tape - 6mm Digital Video
|
||||
DMI, // Tape - Exabyte DMI and compatibles
|
||||
SONY_D2, // Tape - Sony D2S and D2L
|
||||
CLEANER_CARTRIDGE, // Cleaner - All Drive types that support Drive Cleaners
|
||||
CD_ROM, // Opt_Disk - CD
|
||||
CD_R, // Opt_Disk - CD-Recordable (Write Once)
|
||||
CD_RW, // Opt_Disk - CD-Rewriteable
|
||||
DVD_ROM, // Opt_Disk - DVD-ROM
|
||||
DVD_R, // Opt_Disk - DVD-Recordable (Write Once)
|
||||
DVD_RW, // Opt_Disk - DVD-Rewriteable
|
||||
MO_3_RW, // Opt_Disk - 3.5" Rewriteable MO Disk
|
||||
MO_5_WO, // Opt_Disk - MO 5.25" Write Once
|
||||
MO_5_RW, // Opt_Disk - MO 5.25" Rewriteable (not LIMDOW)
|
||||
MO_5_LIMDOW, // Opt_Disk - MO 5.25" Rewriteable (LIMDOW)
|
||||
PC_5_WO, // Opt_Disk - Phase Change 5.25" Write Once Optical
|
||||
PC_5_RW, // Opt_Disk - Phase Change 5.25" Rewriteable
|
||||
PD_5_RW, // Opt_Disk - PhaseChange Dual Rewriteable
|
||||
ABL_5_WO, // Opt_Disk - Ablative 5.25" Write Once Optical
|
||||
PINNACLE_APEX_5_RW, // Opt_Disk - Pinnacle Apex 4.6GB Rewriteable Optical
|
||||
SONY_12_WO, // Opt_Disk - Sony 12" Write Once
|
||||
PHILIPS_12_WO, // Opt_Disk - Philips/LMS 12" Write Once
|
||||
HITACHI_12_WO, // Opt_Disk - Hitachi 12" Write Once
|
||||
CYGNET_12_WO, // Opt_Disk - Cygnet/ATG 12" Write Once
|
||||
KODAK_14_WO, // Opt_Disk - Kodak 14" Write Once
|
||||
MO_NFR_525, // Opt_Disk - Near Field Recording (Terastor)
|
||||
NIKON_12_RW, // Opt_Disk - Nikon 12" Rewriteable
|
||||
IOMEGA_ZIP, // Mag_Disk - Iomega Zip
|
||||
IOMEGA_JAZ, // Mag_Disk - Iomega Jaz
|
||||
SYQUEST_EZ135, // Mag_Disk - Syquest EZ135
|
||||
SYQUEST_EZFLYER, // Mag_Disk - Syquest EzFlyer
|
||||
SYQUEST_SYJET, // Mag_Disk - Syquest SyJet
|
||||
AVATAR_F2, // Mag_Disk - 2.5" Floppy
|
||||
MP2_8mm, // Tape - 8mm Hitachi
|
||||
DST_S, // Ampex DST Small Tapes
|
||||
DST_M, // Ampex DST Medium Tapes
|
||||
DST_L, // Ampex DST Large Tapes
|
||||
VXATape_1, // Ecrix 8mm Tape
|
||||
VXATape_2, // Ecrix 8mm Tape
|
||||
STK_9840, // STK 9840
|
||||
LTO_Ultrium, // IBM, HP, Seagate LTO Ultrium
|
||||
LTO_Accelis, // IBM, HP, Seagate LTO Accelis
|
||||
DVD_RAM, // Opt_Disk - DVD-RAM
|
||||
AIT_8mm, // AIT2 or higher
|
||||
ADR_1, // OnStream ADR Mediatypes
|
||||
ADR_2
|
||||
} STORAGE_MEDIA_TYPE, *PSTORAGE_MEDIA_TYPE;
|
||||
|
||||
#define MEDIA_ERASEABLE 0x00000001
|
||||
#define MEDIA_WRITE_ONCE 0x00000002
|
||||
#define MEDIA_READ_ONLY 0x00000004
|
||||
#define MEDIA_READ_WRITE 0x00000008
|
||||
|
||||
#define MEDIA_WRITE_PROTECTED 0x00000100
|
||||
#define MEDIA_CURRENTLY_MOUNTED 0x80000000
|
||||
|
||||
//
|
||||
// Define the different storage bus types
|
||||
// Bus types below 128 (0x80) are reserved for Microsoft use
|
||||
//
|
||||
|
||||
typedef enum _STORAGE_BUS_TYPE {
|
||||
BusTypeUnknown = 0x00,
|
||||
BusTypeScsi,
|
||||
BusTypeAtapi,
|
||||
BusTypeAta,
|
||||
BusType1394,
|
||||
BusTypeSsa,
|
||||
BusTypeFibre,
|
||||
BusTypeUsb,
|
||||
BusTypeRAID,
|
||||
BusTypeMaxReserved = 0x7F
|
||||
} STORAGE_BUS_TYPE, *PSTORAGE_BUS_TYPE;
|
||||
|
||||
typedef struct _DEVICE_MEDIA_INFO {
|
||||
union {
|
||||
struct {
|
||||
LARGE_INTEGER Cylinders;
|
||||
STORAGE_MEDIA_TYPE MediaType;
|
||||
ULONG TracksPerCylinder;
|
||||
ULONG SectorsPerTrack;
|
||||
ULONG BytesPerSector;
|
||||
ULONG NumberMediaSides;
|
||||
ULONG MediaCharacteristics; // Bitmask of MEDIA_XXX values.
|
||||
} DiskInfo;
|
||||
|
||||
struct {
|
||||
LARGE_INTEGER Cylinders;
|
||||
STORAGE_MEDIA_TYPE MediaType;
|
||||
ULONG TracksPerCylinder;
|
||||
ULONG SectorsPerTrack;
|
||||
ULONG BytesPerSector;
|
||||
ULONG NumberMediaSides;
|
||||
ULONG MediaCharacteristics; // Bitmask of MEDIA_XXX values.
|
||||
} RemovableDiskInfo;
|
||||
|
||||
struct {
|
||||
STORAGE_MEDIA_TYPE MediaType;
|
||||
ULONG MediaCharacteristics; // Bitmask of MEDIA_XXX values.
|
||||
ULONG CurrentBlockSize;
|
||||
STORAGE_BUS_TYPE BusType;
|
||||
|
||||
//
|
||||
// Bus specific information describing the medium supported.
|
||||
//
|
||||
|
||||
union {
|
||||
struct {
|
||||
UCHAR MediumType;
|
||||
UCHAR DensityCode;
|
||||
} ScsiInformation;
|
||||
} BusSpecificData;
|
||||
|
||||
} TapeInfo;
|
||||
} DeviceSpecific;
|
||||
} DEVICE_MEDIA_INFO, *PDEVICE_MEDIA_INFO;
|
||||
|
||||
typedef struct _GET_MEDIA_TYPES {
|
||||
ULONG DeviceType; // FILE_DEVICE_XXX values
|
||||
ULONG MediaInfoCount;
|
||||
DEVICE_MEDIA_INFO MediaInfo[1];
|
||||
} GET_MEDIA_TYPES, *PGET_MEDIA_TYPES;
|
||||
|
||||
|
||||
//
|
||||
// IOCTL_STORAGE_PREDICT_FAILURE
|
||||
//
|
||||
// input - none
|
||||
//
|
||||
// output - STORAGE_PREDICT_FAILURE structure
|
||||
// PredictFailure returns zero if no failure predicted and non zero
|
||||
// if a failure is predicted.
|
||||
//
|
||||
// VendorSpecific returns 512 bytes of vendor specific information
|
||||
// if a failure is predicted
|
||||
//
|
||||
typedef struct _STORAGE_PREDICT_FAILURE
|
||||
{
|
||||
ULONG PredictFailure;
|
||||
UCHAR VendorSpecific[512];
|
||||
} STORAGE_PREDICT_FAILURE, *PSTORAGE_PREDICT_FAILURE;
|
||||
|
||||
// end_ntminitape
|
||||
// end_winioctl
|
||||
|
||||
//
|
||||
// Property Query Structures
|
||||
//
|
||||
|
||||
//
|
||||
// IOCTL_STORAGE_QUERY_PROPERTY
|
||||
//
|
||||
// Input Buffer:
|
||||
// a STORAGE_PROPERTY_QUERY structure which describes what type of query
|
||||
// is being done, what property is being queried for, and any additional
|
||||
// parameters which a particular property query requires.
|
||||
//
|
||||
// Output Buffer:
|
||||
// Contains a buffer to place the results of the query into. Since all
|
||||
// property descriptors can be cast into a STORAGE_DESCRIPTOR_HEADER,
|
||||
// the IOCTL can be called once with a small buffer then again using
|
||||
// a buffer as large as the header reports is necessary.
|
||||
//
|
||||
|
||||
|
||||
//
|
||||
// Types of queries
|
||||
//
|
||||
|
||||
typedef enum _STORAGE_QUERY_TYPE {
|
||||
PropertyStandardQuery = 0, // Retrieves the descriptor
|
||||
PropertyExistsQuery, // Used to test whether the descriptor is supported
|
||||
PropertyMaskQuery, // Used to retrieve a mask of writeable fields in the descriptor
|
||||
PropertyQueryMaxDefined // use to validate the value
|
||||
} STORAGE_QUERY_TYPE, *PSTORAGE_QUERY_TYPE;
|
||||
|
||||
//
|
||||
// define some initial property id's
|
||||
//
|
||||
|
||||
typedef enum _STORAGE_PROPERTY_ID {
|
||||
StorageDeviceProperty = 0,
|
||||
StorageAdapterProperty,
|
||||
StorageDeviceIdProperty
|
||||
} STORAGE_PROPERTY_ID, *PSTORAGE_PROPERTY_ID;
|
||||
|
||||
//
|
||||
// Query structure - additional parameters for specific queries can follow
|
||||
// the header
|
||||
//
|
||||
|
||||
typedef struct _STORAGE_PROPERTY_QUERY {
|
||||
|
||||
//
|
||||
// ID of the property being retrieved
|
||||
//
|
||||
|
||||
STORAGE_PROPERTY_ID PropertyId;
|
||||
|
||||
//
|
||||
// Flags indicating the type of query being performed
|
||||
//
|
||||
|
||||
STORAGE_QUERY_TYPE QueryType;
|
||||
|
||||
//
|
||||
// Space for additional parameters if necessary
|
||||
//
|
||||
|
||||
UCHAR AdditionalParameters[1];
|
||||
|
||||
} STORAGE_PROPERTY_QUERY, *PSTORAGE_PROPERTY_QUERY;
|
||||
|
||||
//
|
||||
// Standard property descriptor header. All property pages should use this
|
||||
// as their first element or should contain these two elements
|
||||
//
|
||||
|
||||
typedef struct _STORAGE_DESCRIPTOR_HEADER {
|
||||
|
||||
ULONG Version;
|
||||
|
||||
ULONG Size;
|
||||
|
||||
} STORAGE_DESCRIPTOR_HEADER, *PSTORAGE_DESCRIPTOR_HEADER;
|
||||
|
||||
//
|
||||
// Device property descriptor - this is really just a rehash of the inquiry
|
||||
// data retrieved from a scsi device
|
||||
//
|
||||
// This may only be retrieved from a target device. Sending this to the bus
|
||||
// will result in an error
|
||||
//
|
||||
|
||||
typedef struct _STORAGE_DEVICE_DESCRIPTOR {
|
||||
|
||||
//
|
||||
// Sizeof(STORAGE_DEVICE_DESCRIPTOR)
|
||||
//
|
||||
|
||||
ULONG Version;
|
||||
|
||||
//
|
||||
// Total size of the descriptor, including the space for additional
|
||||
// data and id strings
|
||||
//
|
||||
|
||||
ULONG Size;
|
||||
|
||||
//
|
||||
// The SCSI-2 device type
|
||||
//
|
||||
|
||||
UCHAR DeviceType;
|
||||
|
||||
//
|
||||
// The SCSI-2 device type modifier (if any) - this may be zero
|
||||
//
|
||||
|
||||
UCHAR DeviceTypeModifier;
|
||||
|
||||
//
|
||||
// Flag indicating whether the device's media (if any) is removable. This
|
||||
// field should be ignored for media-less devices
|
||||
//
|
||||
|
||||
BOOLEAN RemovableMedia;
|
||||
|
||||
//
|
||||
// Flag indicating whether the device can support mulitple outstanding
|
||||
// commands. The actual synchronization in this case is the responsibility
|
||||
// of the port driver.
|
||||
//
|
||||
|
||||
BOOLEAN CommandQueueing;
|
||||
|
||||
//
|
||||
// Byte offset to the zero-terminated ascii string containing the device's
|
||||
// vendor id string. For devices with no such ID this will be zero
|
||||
//
|
||||
|
||||
ULONG VendorIdOffset;
|
||||
|
||||
//
|
||||
// Byte offset to the zero-terminated ascii string containing the device's
|
||||
// product id string. For devices with no such ID this will be zero
|
||||
//
|
||||
|
||||
ULONG ProductIdOffset;
|
||||
|
||||
//
|
||||
// Byte offset to the zero-terminated ascii string containing the device's
|
||||
// product revision string. For devices with no such string this will be
|
||||
// zero
|
||||
//
|
||||
|
||||
ULONG ProductRevisionOffset;
|
||||
|
||||
//
|
||||
// Byte offset to the zero-terminated ascii string containing the device's
|
||||
// serial number. For devices with no serial number this will be zero
|
||||
//
|
||||
|
||||
ULONG SerialNumberOffset;
|
||||
|
||||
//
|
||||
// Contains the bus type (as defined above) of the device. It should be
|
||||
// used to interpret the raw device properties at the end of this structure
|
||||
// (if any)
|
||||
//
|
||||
|
||||
STORAGE_BUS_TYPE BusType;
|
||||
|
||||
//
|
||||
// The number of bytes of bus-specific data which have been appended to
|
||||
// this descriptor
|
||||
//
|
||||
|
||||
ULONG RawPropertiesLength;
|
||||
|
||||
//
|
||||
// Place holder for the first byte of the bus specific property data
|
||||
//
|
||||
|
||||
UCHAR RawDeviceProperties[1];
|
||||
|
||||
} STORAGE_DEVICE_DESCRIPTOR, *PSTORAGE_DEVICE_DESCRIPTOR;
|
||||
|
||||
|
||||
//
|
||||
// Adapter properties
|
||||
//
|
||||
// This descriptor can be retrieved from a target device object of from the
|
||||
// device object for the bus. Retrieving from the target device object will
|
||||
// forward the request to the underlying bus
|
||||
//
|
||||
|
||||
typedef struct _STORAGE_ADAPTER_DESCRIPTOR {
|
||||
|
||||
ULONG Version;
|
||||
|
||||
ULONG Size;
|
||||
|
||||
ULONG MaximumTransferLength;
|
||||
|
||||
ULONG MaximumPhysicalPages;
|
||||
|
||||
ULONG AlignmentMask;
|
||||
|
||||
BOOLEAN AdapterUsesPio;
|
||||
|
||||
BOOLEAN AdapterScansDown;
|
||||
|
||||
BOOLEAN CommandQueueing;
|
||||
|
||||
BOOLEAN AcceleratedTransfer;
|
||||
|
||||
UCHAR BusType;
|
||||
|
||||
USHORT BusMajorVersion;
|
||||
|
||||
USHORT BusMinorVersion;
|
||||
|
||||
} STORAGE_ADAPTER_DESCRIPTOR, *PSTORAGE_ADAPTER_DESCRIPTOR;
|
||||
|
||||
//
|
||||
// Storage identification descriptor.
|
||||
// The definitions here are based on the SCSI/SBP vital product data
|
||||
// device identifier page.
|
||||
//
|
||||
|
||||
typedef enum _STORAGE_IDENTIFIER_CODE_SET {
|
||||
StorageIdCodeSetReserved = 0,
|
||||
StorageIdCodeSetBinary = 1,
|
||||
StorageIdCodeSetAscii = 2
|
||||
} STORAGE_IDENTIFIER_CODE_SET, *PSTORAGE_IDENTIFIER_CODE_SET;
|
||||
|
||||
typedef enum _STORAGE_IDENTIFIER_TYPE {
|
||||
StorageIdTypeVendorSpecific = 0,
|
||||
StorageIdTypeVendorId = 1,
|
||||
StorageIdTypeEUI64 = 2,
|
||||
StorageIdTypeFCPHName = 3,
|
||||
StorageIdTypePortRelative = 4
|
||||
} STORAGE_IDENTIFIER_TYPE, *PSTORAGE_IDENTIFIER_TYPE;
|
||||
|
||||
typedef enum _STORAGE_ASSOCIATION_TYPE {
|
||||
StorageIdAssocDevice = 0,
|
||||
StorageIdAssocPort = 1
|
||||
} STORAGE_ASSOCIATION_TYPE, *PSTORAGE_ASSOCIATION_TYPE;
|
||||
|
||||
typedef struct _STORAGE_IDENTIFIER {
|
||||
STORAGE_IDENTIFIER_CODE_SET CodeSet;
|
||||
STORAGE_IDENTIFIER_TYPE Type;
|
||||
USHORT IdentifierSize;
|
||||
USHORT NextOffset;
|
||||
|
||||
//
|
||||
// Add new fields here since existing code depends on
|
||||
// the above layout not changing.
|
||||
//
|
||||
|
||||
STORAGE_ASSOCIATION_TYPE Association;
|
||||
|
||||
//
|
||||
// The identifier is a variable length array of bytes.
|
||||
//
|
||||
|
||||
UCHAR Identifier[1];
|
||||
} STORAGE_IDENTIFIER, *PSTORAGE_IDENTIFIER;
|
||||
|
||||
typedef struct _STORAGE_DEVICE_ID_DESCRIPTOR {
|
||||
|
||||
ULONG Version;
|
||||
|
||||
ULONG Size;
|
||||
|
||||
//
|
||||
// The number of identifiers reported by the device.
|
||||
//
|
||||
|
||||
ULONG NumberOfIdentifiers;
|
||||
|
||||
//
|
||||
// The following field is actually a variable length array of identification
|
||||
// descriptors. Unfortunately there's no C notation for an array of
|
||||
// variable length structures so we're forced to just pretend.
|
||||
//
|
||||
|
||||
UCHAR Identifiers[1];
|
||||
} STORAGE_DEVICE_ID_DESCRIPTOR, *PSTORAGE_DEVICE_ID_DESCRIPTOR;
|
||||
|
||||
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4200)
|
||||
typedef struct _STORAGE_MEDIA_SERIAL_NUMBER_DATA {
|
||||
|
||||
USHORT Reserved;
|
||||
|
||||
//
|
||||
// the SerialNumberLength will be set to zero
|
||||
// if the command is supported and the media
|
||||
// does not have a valid serial number.
|
||||
//
|
||||
|
||||
USHORT SerialNumberLength;
|
||||
|
||||
//
|
||||
// the following data is binary, and is not guaranteed
|
||||
// to be NULL terminated. this is an excercise for the
|
||||
// caller.
|
||||
//
|
||||
|
||||
UCHAR SerialNumber[0];
|
||||
|
||||
} STORAGE_MEDIA_SERIAL_NUMBER_DATA, *PSTORAGE_MEDIA_SERIAL_NUMBER_DATA;
|
||||
#pragma warning(push)
|
||||
|
||||
|
||||
// begin_winioctl
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _NTDDSTOR_H_
|
||||
// end_winioctl
|
||||
|
229
src/dos/cdrom.cpp
Normal file
229
src/dos/cdrom.cpp
Normal file
@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Copyright (C) 2002-2003 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
|
||||
// ******************************************************
|
||||
// SDL CDROM
|
||||
// ******************************************************
|
||||
|
||||
#include "SDL.h"
|
||||
#include "support.h"
|
||||
#include "cdrom.h"
|
||||
|
||||
CDROM_Interface_SDL::CDROM_Interface_SDL(void)
|
||||
{
|
||||
driveID = 0;
|
||||
oldLeadOut = 0;
|
||||
cd = 0;
|
||||
};
|
||||
|
||||
CDROM_Interface_SDL::~CDROM_Interface_SDL(void)
|
||||
{
|
||||
StopAudio();
|
||||
SDL_CDClose(cd);
|
||||
cd = 0;
|
||||
};
|
||||
|
||||
bool CDROM_Interface_SDL::SetDevice (char* path, int forceCD)
|
||||
{
|
||||
char buffer[512];
|
||||
strcpy(buffer,path);
|
||||
upcase(buffer);
|
||||
|
||||
int num = SDL_CDNumDrives();
|
||||
if ((forceCD>=0) && (forceCD<num)) {
|
||||
driveID = forceCD;
|
||||
return true;
|
||||
};
|
||||
|
||||
const char* cdname = 0;
|
||||
for (int i=0; i<num; i++) {
|
||||
cdname = SDL_CDName(i);
|
||||
if (strcmp(buffer,cdname)==0) {
|
||||
cd = SDL_CDOpen(i);
|
||||
SDL_CDStatus(cd);
|
||||
driveID = i;
|
||||
return true;
|
||||
};
|
||||
};
|
||||
return false;
|
||||
};
|
||||
|
||||
bool CDROM_Interface_SDL::GetAudioTracks (int& stTrack, int& end, TMSF& leadOut)
|
||||
{
|
||||
SDL_CDStatus(cd);
|
||||
if (CD_INDRIVE(cd->status)) {
|
||||
stTrack = 1;
|
||||
end = cd->numtracks;
|
||||
FRAMES_TO_MSF(cd->track[cd->numtracks].offset,&leadOut.min,&leadOut.sec,&leadOut.fr);
|
||||
}
|
||||
return CD_INDRIVE(cd->status);
|
||||
};
|
||||
|
||||
bool CDROM_Interface_SDL::GetAudioTrackInfo (int track, TMSF& start, unsigned char& attr)
|
||||
{
|
||||
SDL_CDStatus(cd);
|
||||
if (CD_INDRIVE(cd->status)) {
|
||||
FRAMES_TO_MSF(cd->track[track-1].offset+150,&start.min,&start.sec,&start.fr);
|
||||
attr = cd->track[track-1].type;
|
||||
}
|
||||
return CD_INDRIVE(cd->status);
|
||||
};
|
||||
|
||||
bool CDROM_Interface_SDL::GetAudioSub (unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos)
|
||||
{
|
||||
SDL_CDStatus(cd);
|
||||
if (CD_INDRIVE(cd->status)) {
|
||||
track = cd->cur_track;
|
||||
index = cd->cur_track;
|
||||
attr = cd->track[track].type;
|
||||
FRAMES_TO_MSF(cd->cur_frame,&relPos.min,&relPos.sec,&relPos.fr);
|
||||
FRAMES_TO_MSF(cd->cur_frame+cd->track[track].offset,&absPos.min,&absPos.sec,&absPos.fr);
|
||||
}
|
||||
return CD_INDRIVE(cd->status);
|
||||
};
|
||||
|
||||
bool CDROM_Interface_SDL::GetAudioStatus (bool& playing, bool& pause)
|
||||
{
|
||||
SDL_CDStatus(cd);
|
||||
if (CD_INDRIVE(cd->status)) {
|
||||
playing = (cd->status==CD_PLAYING);
|
||||
pause = (cd->status==CD_PAUSED);
|
||||
}
|
||||
return CD_INDRIVE(cd->status);
|
||||
};
|
||||
|
||||
bool CDROM_Interface_SDL::GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen)
|
||||
{
|
||||
SDL_CDStatus(cd);
|
||||
mediaPresent = (cd->status!=CD_TRAYEMPTY) && (cd->status!=CD_ERROR);
|
||||
mediaChanged = (oldLeadOut!=cd->track[cd->numtracks].offset);
|
||||
trayOpen = !mediaPresent;
|
||||
oldLeadOut = cd->track[cd->numtracks].offset;
|
||||
if (mediaChanged) SDL_CDStatus(cd);
|
||||
return true;
|
||||
};
|
||||
|
||||
bool CDROM_Interface_SDL::PlayAudioSector (unsigned long start,unsigned long len)
|
||||
{
|
||||
// Has to be there, otherwise wrong cd status report (dunno why, sdl bug ?)
|
||||
SDL_CDClose(cd);
|
||||
cd = SDL_CDOpen(driveID);
|
||||
bool success = (SDL_CDPlay(cd,start,len)==0);
|
||||
return success;
|
||||
};
|
||||
|
||||
bool CDROM_Interface_SDL::PauseAudio (bool resume)
|
||||
{
|
||||
bool success;
|
||||
if (resume) success = (SDL_CDResume(cd)==0);
|
||||
else success = (SDL_CDPause (cd)==0);
|
||||
return success;
|
||||
};
|
||||
|
||||
bool CDROM_Interface_SDL::StopAudio (void)
|
||||
{
|
||||
// Has to be there, otherwise wrong cd status report (dunno why, sdl bug ?)
|
||||
SDL_CDClose(cd);
|
||||
cd = SDL_CDOpen(driveID);
|
||||
bool success = (SDL_CDStop(cd)==0);
|
||||
return success;
|
||||
};
|
||||
|
||||
bool CDROM_Interface_SDL::LoadUnloadMedia(bool unload)
|
||||
{
|
||||
bool success = (SDL_CDEject(cd)==0);
|
||||
return success;
|
||||
};
|
||||
|
||||
int CDROM_GetMountType(char* path, int forceCD)
|
||||
// 0 - physical CDROM
|
||||
// 1 - Iso file
|
||||
// 2 - subdirectory
|
||||
{
|
||||
// 1. Smells like a real cdrom
|
||||
// if ((strlen(path)<=3) && (path[2]=='\\') && (strchr(path,'\\')==strrchr(path,'\\')) && (GetDriveType(path)==DRIVE_CDROM)) return 0;
|
||||
|
||||
const char* cdName;
|
||||
char buffer[512];
|
||||
strcpy(buffer,path);
|
||||
#if defined (WIN32)
|
||||
upcase(buffer);
|
||||
#endif
|
||||
|
||||
int num = SDL_CDNumDrives();
|
||||
// If cd drive is forced then check if its in range and return 0
|
||||
if ((forceCD>=0) && (forceCD<num)) {
|
||||
LOG(LOG_ERROR,"CDROM: Using drive %d",forceCD);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// compare names
|
||||
for (int i=0; i<num; i++) {
|
||||
cdName = SDL_CDName(i);
|
||||
if (strcmp(buffer,cdName)==0) return 0;
|
||||
};
|
||||
// TODO: Detect ISO
|
||||
return 2;
|
||||
};
|
||||
|
||||
// ******************************************************
|
||||
// Fake CDROM
|
||||
// ******************************************************
|
||||
|
||||
bool CDROM_Interface_Fake :: GetAudioTracks (int& stTrack, int& end, TMSF& leadOut)
|
||||
{
|
||||
stTrack = end = 1;
|
||||
leadOut.min = 60;
|
||||
leadOut.sec = leadOut.fr = 0;
|
||||
return true;
|
||||
};
|
||||
|
||||
bool CDROM_Interface_Fake :: GetAudioTrackInfo (int track, TMSF& start, unsigned char& attr)
|
||||
{
|
||||
if (track>1) return false;
|
||||
start.min = start.fr = 0;
|
||||
start.sec = 2;
|
||||
attr = 0x60; // data / permitted
|
||||
return true;
|
||||
};
|
||||
|
||||
bool CDROM_Interface_Fake :: GetAudioSub (unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos)
|
||||
{
|
||||
attr = 0;
|
||||
track = index = 1;
|
||||
relPos.min = relPos.fr = 0; relPos.sec = 2;
|
||||
absPos.min = absPos.fr = 0; absPos.sec = 2;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Fake :: GetAudioStatus (bool& playing, bool& pause)
|
||||
{
|
||||
playing = pause = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Fake :: GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen)
|
||||
{
|
||||
mediaPresent = true;
|
||||
mediaChanged = false;
|
||||
trayOpen = false;
|
||||
return true;
|
||||
};
|
||||
|
||||
|
183
src/dos/cdrom.h
Normal file
183
src/dos/cdrom.h
Normal file
@ -0,0 +1,183 @@
|
||||
|
||||
#ifndef __CDROM_INTERFACE__
|
||||
#define __CDROM_INTERFACE__
|
||||
|
||||
#define MAX_ASPI_CDROM 5
|
||||
|
||||
#include <string.h>
|
||||
#include "SDL.h"
|
||||
|
||||
#define RAW_SECTOR_SIZE 2352
|
||||
#define COOKED_SECTOR_SIZE 2048
|
||||
|
||||
enum { CDROM_USE_SDL, CDROM_USE_ASPI, CDROM_USE_IOCTL };
|
||||
|
||||
typedef struct SMSF {
|
||||
unsigned char min;
|
||||
unsigned char sec;
|
||||
unsigned char fr;
|
||||
} TMSF;
|
||||
|
||||
extern int CDROM_GetMountType(char* path, int force);
|
||||
|
||||
class CDROM_Interface
|
||||
{
|
||||
public:
|
||||
// CDROM_Interface (void);
|
||||
virtual ~CDROM_Interface (void) {};
|
||||
|
||||
virtual bool SetDevice (char* path, int forceCD) = 0;
|
||||
|
||||
virtual bool GetUPC (unsigned char& attr, char* upc) = 0;
|
||||
|
||||
virtual bool GetAudioTracks (int& stTrack, int& end, TMSF& leadOut) = 0;
|
||||
virtual bool GetAudioTrackInfo (int track, TMSF& start, unsigned char& attr) = 0;
|
||||
virtual bool GetAudioSub (unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos) = 0;
|
||||
virtual bool GetAudioStatus (bool& playing, bool& pause) = 0;
|
||||
virtual bool GetMediaTrayStatus (bool& mediaPresent, bool& mediaChanged, bool& trayOpen) = 0;
|
||||
|
||||
virtual bool PlayAudioSector (unsigned long start,unsigned long len) = 0;
|
||||
virtual bool PauseAudio (bool resume) = 0;
|
||||
virtual bool StopAudio (void) = 0;
|
||||
|
||||
virtual bool ReadSectors (void* buffer, bool raw, unsigned long sector, unsigned long num) = 0;
|
||||
|
||||
virtual bool LoadUnloadMedia (bool unload) = 0;
|
||||
};
|
||||
|
||||
class CDROM_Interface_SDL : public CDROM_Interface
|
||||
{
|
||||
public:
|
||||
CDROM_Interface_SDL (void);
|
||||
~CDROM_Interface_SDL (void);
|
||||
|
||||
bool SetDevice (char* path, int forceCD);
|
||||
bool GetUPC (unsigned char& attr, char* upc) { attr = 0; strcpy(upc,"UPC"); return true; };
|
||||
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 (void* buffer, bool raw, unsigned long sector, unsigned long num) { return true; };
|
||||
bool LoadUnloadMedia (bool unload);
|
||||
|
||||
private:
|
||||
bool Open (void);
|
||||
void Close (void);
|
||||
|
||||
SDL_CD* cd;
|
||||
int driveID;
|
||||
Uint32 oldLeadOut;
|
||||
};
|
||||
|
||||
class CDROM_Interface_Fake : public CDROM_Interface
|
||||
{
|
||||
public:
|
||||
bool SetDevice (char* path, int forceCD) { return true; };
|
||||
bool GetUPC (unsigned char& attr, char* upc) { attr = 0; strcpy(upc,"UPC"); return true; };
|
||||
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) { return true; };
|
||||
bool PauseAudio (bool resume) { return true; };
|
||||
bool StopAudio (void) { return true; };
|
||||
bool ReadSectors (void* buffer, bool raw, unsigned long sector, unsigned long num) { return true; };
|
||||
bool LoadUnloadMedia (bool unload) { return true; };
|
||||
};
|
||||
|
||||
#if defined (WIN32) /* Win 32 */
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
|
||||
#include <windows.h>
|
||||
#include "wnaspi32.h" // Aspi stuff
|
||||
|
||||
class CDROM_Interface_Aspi : public CDROM_Interface
|
||||
{
|
||||
public:
|
||||
CDROM_Interface_Aspi (void);
|
||||
~CDROM_Interface_Aspi (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 (void* buffer, bool raw, unsigned long sector, unsigned long num);
|
||||
|
||||
bool LoadUnloadMedia (bool unload);
|
||||
|
||||
private:
|
||||
DWORD GetTOC (LPTOC toc);
|
||||
HANDLE OpenIOCTLFile (char cLetter, BOOL bAsync);
|
||||
void GetIOCTLAdapter (HANDLE hF,int * iDA,int * iDT,int * iDL);
|
||||
bool ScanRegistryFindKey (HKEY& hKeyBase);
|
||||
bool ScanRegistry (HKEY& hKeyBase);
|
||||
BYTE GetHostAdapter (char* hardwareID);
|
||||
bool GetVendor (BYTE HA_num, BYTE SCSI_Id, BYTE SCSI_Lun, char* szBuffer);
|
||||
|
||||
// ASPI stuff
|
||||
BYTE haId;
|
||||
BYTE target;
|
||||
BYTE lun;
|
||||
char letter;
|
||||
|
||||
// Windows stuff
|
||||
HINSTANCE hASPI;
|
||||
HANDLE hEvent; // global event
|
||||
DWORD (*pGetASPI32SupportInfo) (void); // ptrs to aspi funcs
|
||||
DWORD (*pSendASPI32Command) (LPSRB);
|
||||
TMSF oldLeadOut;
|
||||
};
|
||||
|
||||
class CDROM_Interface_Ioctl : public CDROM_Interface
|
||||
{
|
||||
public:
|
||||
CDROM_Interface_Ioctl (void);
|
||||
~CDROM_Interface_Ioctl (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 (void* buffer, bool raw, unsigned long sector, unsigned long num);
|
||||
|
||||
bool LoadUnloadMedia (bool unload);
|
||||
|
||||
private:
|
||||
|
||||
bool Open (void);
|
||||
void Close (void);
|
||||
|
||||
char pathname[32];
|
||||
HANDLE hIOCTL;
|
||||
TMSF oldLeadOut;
|
||||
};
|
||||
|
||||
#endif /* WIN 32 */
|
||||
|
||||
#endif /* __CDROM_INTERFACE__ */
|
735
src/dos/cdrom_aspi_win32.cpp
Normal file
735
src/dos/cdrom_aspi_win32.cpp
Normal file
@ -0,0 +1,735 @@
|
||||
/*
|
||||
* Copyright (C) 2002-2003 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#if defined (WIN32)
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "cdrom.h"
|
||||
#include "scsidefs.h" // Aspi stuff
|
||||
#include "dosbox.h"
|
||||
|
||||
// *****************************************************************
|
||||
// Windows ASPI functions (should work for all WIN with ASPI layer)
|
||||
// *****************************************************************
|
||||
|
||||
CDROM_Interface_Aspi::CDROM_Interface_Aspi(void)
|
||||
{
|
||||
hASPI = NULL;
|
||||
hEvent = NULL;
|
||||
pGetASPI32SupportInfo = NULL;
|
||||
pSendASPI32Command = NULL;
|
||||
memset(&oldLeadOut,0,sizeof(oldLeadOut));
|
||||
};
|
||||
|
||||
CDROM_Interface_Aspi::~CDROM_Interface_Aspi(void)
|
||||
{
|
||||
// Stop Audio
|
||||
StopAudio();
|
||||
|
||||
pGetASPI32SupportInfo = NULL; // clear funcs
|
||||
pSendASPI32Command = NULL;
|
||||
|
||||
if (hASPI) { // free aspi
|
||||
FreeLibrary(hASPI);
|
||||
hASPI=NULL;
|
||||
}
|
||||
};
|
||||
|
||||
bool GetRegistryValue(HKEY& hKey,char* valueName, char* buffer, ULONG bufferSize)
|
||||
// hKey has to be open
|
||||
{
|
||||
// Read subkey
|
||||
ULONG valType;
|
||||
ULONG result;
|
||||
result = RegQueryValueEx(hKey,valueName,NULL,&valType,(unsigned char*)&buffer[0],&bufferSize);
|
||||
return (result == ERROR_SUCCESS);
|
||||
};
|
||||
|
||||
BYTE CDROM_Interface_Aspi::GetHostAdapter(char* hardwareID)
|
||||
{
|
||||
SRB_HAInquiry sh;
|
||||
SRB_GDEVBlock sd;
|
||||
DWORD d = pGetASPI32SupportInfo();
|
||||
int cnt = LOBYTE(LOWORD(d));
|
||||
int i,j,k,max;
|
||||
|
||||
for(i=0; i<cnt; i++) {
|
||||
memset(&sh, 0, sizeof(sh));
|
||||
sh.SRB_Cmd = SC_HA_INQUIRY;
|
||||
sh.SRB_HaId = i;
|
||||
pSendASPI32Command((LPSRB)&sh);
|
||||
if (sh.SRB_Status!=SS_COMP) continue;
|
||||
|
||||
// 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
|
||||
max = (int)sh.HA_Unique[3];
|
||||
if ((max!=8) && (max!=16)) max = 8;
|
||||
|
||||
for(j=0; j<max; j++) {
|
||||
for(k=0; k<8; k++) {
|
||||
memset(&sd, 0, sizeof(sd));
|
||||
sd.SRB_Cmd = SC_GET_DEV_TYPE;
|
||||
sd.SRB_HaId = i;
|
||||
sd.SRB_Target = j;
|
||||
sd.SRB_Lun = k;
|
||||
pSendASPI32Command((LPSRB)&sd);
|
||||
if (sd.SRB_Status == SS_COMP) {
|
||||
if (sd.SRB_DeviceType == DTYPE_CDROM) {
|
||||
if ((target==j) && (lun==k)) {
|
||||
LOG(LOG_MISC,"SCSI: Getting Hardware vendor.");
|
||||
// "Hardware ID = vendor" match ?
|
||||
char vendor[64];
|
||||
if (GetVendor(i,target,lun,vendor)) {
|
||||
LOG(LOG_MISC,"SCSI: Vendor : %s",vendor);
|
||||
if (strstr(strupr(hardwareID),strupr(vendor))) {
|
||||
LOG(LOG_MISC,"SCSI: Host Adapter found: %d",i);
|
||||
return i;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
LOG(LOG_ERROR,"SCSI: Host Adapter not found: %d",i);
|
||||
return 0;
|
||||
};
|
||||
|
||||
bool CDROM_Interface_Aspi::ScanRegistryFindKey(HKEY& hKeyBase)
|
||||
// hKey has to be open
|
||||
{
|
||||
FILETIME time;
|
||||
ULONG result,newKeyResult;
|
||||
char subKey[256];
|
||||
char buffer[256];
|
||||
ULONG bufferSize = 256;
|
||||
ULONG subKeySize = 256;
|
||||
HKEY hNewKey;
|
||||
|
||||
ULONG index = 0;
|
||||
do {
|
||||
result = RegEnumKeyEx (hKeyBase,index,&subKey[0],&subKeySize,NULL,NULL,0,&time);
|
||||
if (result==ERROR_SUCCESS) {
|
||||
// Open Key...
|
||||
newKeyResult = RegOpenKeyEx (hKeyBase,subKey,0,KEY_READ,&hNewKey);
|
||||
if (newKeyResult==ERROR_SUCCESS) {
|
||||
if (GetRegistryValue(hNewKey,"CurrentDriveLetterAssignment",buffer,256)) {
|
||||
LOG(LOG_MISC,"SCSI: Drive Letter found: %s",buffer);
|
||||
// aha, something suspicious...
|
||||
if (buffer[0]==letter) {
|
||||
char hardwareID[256];
|
||||
// found it... lets see if we can get the scsi values
|
||||
bool v1 = GetRegistryValue(hNewKey,"SCSILUN",buffer,256);
|
||||
LOG(LOG_MISC,"SCSI: SCSILUN found: %s",buffer);
|
||||
lun = buffer[0]-'0';
|
||||
bool v2 = GetRegistryValue(hNewKey,"SCSITargetID",buffer,256);
|
||||
LOG(LOG_MISC,"SCSI: SCSITargetID found: %s",buffer);
|
||||
target = buffer[0]-'0';
|
||||
bool v3 = GetRegistryValue(hNewKey,"HardwareID",hardwareID,256);
|
||||
RegCloseKey(hNewKey);
|
||||
if (v1 && v2 && v3) {
|
||||
haId = GetHostAdapter(hardwareID);
|
||||
return true;
|
||||
};
|
||||
}
|
||||
};
|
||||
};
|
||||
RegCloseKey(hNewKey);
|
||||
};
|
||||
index++;
|
||||
} while ((result==ERROR_SUCCESS) || (result==ERROR_MORE_DATA));
|
||||
return false;
|
||||
};
|
||||
|
||||
bool CDROM_Interface_Aspi::GetVendor(BYTE HA_num, BYTE SCSI_Id, BYTE SCSI_Lun, char* szBuffer)
|
||||
{
|
||||
SRB_ExecSCSICmd srbExec;
|
||||
memset ( &srbExec, 0, sizeof ( SRB_ExecSCSICmd ) );
|
||||
|
||||
hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
||||
|
||||
srbExec.SRB_Cmd = SC_EXEC_SCSI_CMD ;
|
||||
srbExec.SRB_HaId = HA_num;
|
||||
srbExec.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
||||
srbExec.SRB_Target = SCSI_Id;
|
||||
srbExec.SRB_Lun = SCSI_Lun;
|
||||
srbExec.SRB_BufLen = 36;
|
||||
srbExec.SRB_BufPointer = (unsigned char*)szBuffer;
|
||||
srbExec.SRB_SenseLen = SENSE_LEN;
|
||||
srbExec.SRB_CDBLen = 6;
|
||||
srbExec.SRB_PostProc = (LPVOID)hEvent;
|
||||
srbExec.CDBByte [ 0 ] = SCSI_INQUIRY;
|
||||
srbExec.CDBByte [ 4 ] = 36; // allocation length per szBuffer [ ]
|
||||
|
||||
ResetEvent(hEvent);
|
||||
int dwStatus = pSendASPI32Command ((LPSRB)&srbExec);
|
||||
// LOG(LOG_MISC|LOG_ERROR,"SCSI: Get vendor command send");
|
||||
|
||||
if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,30000);
|
||||
// LOG(LOG_MISC|LOG_ERROR,"SCSI: Pending done.");
|
||||
|
||||
CloseHandle(hEvent);
|
||||
if (srbExec.SRB_Status != SS_COMP) {
|
||||
strcpy (szBuffer, "error" );
|
||||
return false;
|
||||
} else {
|
||||
strncpy(szBuffer,szBuffer+8,25);
|
||||
szBuffer[25] = 0;
|
||||
int len = strlen(szBuffer);
|
||||
for (int i=0; i<len; i++) if (szBuffer[i]<=32) szBuffer[i]='_';
|
||||
};
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Aspi::ScanRegistry(HKEY& hKeyBase)
|
||||
// hKey has to be open
|
||||
{
|
||||
FILETIME time;
|
||||
ULONG result,newKeyResult;
|
||||
char subKey[256];
|
||||
ULONG subKeySize= 256;
|
||||
HKEY hNewKey;
|
||||
|
||||
ULONG index = 0;
|
||||
do {
|
||||
result = RegEnumKeyEx (hKeyBase,index,&subKey[0],&subKeySize,NULL,NULL,0,&time);
|
||||
if ((result==ERROR_SUCCESS) || (result==ERROR_MORE_DATA)) {
|
||||
// Open Key...
|
||||
newKeyResult = RegOpenKeyEx (hKeyBase,subKey,0,KEY_READ,&hNewKey);
|
||||
if (newKeyResult==ERROR_SUCCESS) {
|
||||
bool found = ScanRegistryFindKey(hNewKey);
|
||||
RegCloseKey(hNewKey);
|
||||
if (found) return true;
|
||||
};
|
||||
RegCloseKey(hNewKey);
|
||||
};
|
||||
index++;
|
||||
} while ((result==ERROR_SUCCESS) || (result==ERROR_MORE_DATA));
|
||||
return false;
|
||||
};
|
||||
|
||||
bool CDROM_Interface_Aspi::SetDevice(char* path, int forceCD)
|
||||
{
|
||||
// load WNASPI32.DLL
|
||||
hASPI = LoadLibrary ( "WNASPI32.DLL" );
|
||||
if (!hASPI) return false;
|
||||
// Get Pointer to ASPI funcs
|
||||
pGetASPI32SupportInfo = (DWORD(*)(void))GetProcAddress(hASPI,"GetASPI32SupportInfo");
|
||||
pSendASPI32Command = (DWORD(*)(LPSRB))GetProcAddress(hASPI,"SendASPI32Command");
|
||||
if (!pGetASPI32SupportInfo || !pSendASPI32Command) return false;
|
||||
// Letter
|
||||
letter = toupper(path[0]);
|
||||
|
||||
// Check OS
|
||||
OSVERSIONINFO osi;
|
||||
osi.dwOSVersionInfoSize = sizeof(osi);
|
||||
GetVersionEx(&osi);
|
||||
if ((osi.dwPlatformId==VER_PLATFORM_WIN32_NT) && (osi.dwMajorVersion>4)) {
|
||||
if (GetDriveType(path)==DRIVE_CDROM) {
|
||||
// WIN XP/NT/2000
|
||||
int iDA,iDT,iDL;
|
||||
letter = path[0];
|
||||
HANDLE hF = OpenIOCTLFile(letter,FALSE);
|
||||
GetIOCTLAdapter(hF,&iDA,&iDT,&iDL);
|
||||
CloseHandle(hF);
|
||||
// Set SCSI IDs
|
||||
haId = iDA;
|
||||
target = iDT;
|
||||
lun = iDL;
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
// win 95/98/ME have to scan the registry...
|
||||
// lets hope the layout is always the same... i dunno...
|
||||
char key[2048];
|
||||
HKEY hKeyBase;
|
||||
bool found = false;
|
||||
strcpy(key,"ENUM\\SCSI");
|
||||
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE,key,0,KEY_READ,&hKeyBase)==ERROR_SUCCESS) {
|
||||
found = ScanRegistry(hKeyBase);
|
||||
};
|
||||
RegCloseKey(hKeyBase);
|
||||
return found;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
bool CDROM_Interface_Aspi::GetAudioTracks(int& stTrack, int& endTrack, TMSF& leadOut)
|
||||
{
|
||||
TOC toc;
|
||||
if (GetTOC((LPTOC)&toc) == SS_COMP) {
|
||||
stTrack = toc.cFirstTrack;
|
||||
endTrack = toc.cLastTrack;
|
||||
leadOut.min = (unsigned char)(toc.tracks[endTrack].lAddr >> 8) &0xFF;
|
||||
leadOut.sec = (unsigned char)(toc.tracks[endTrack].lAddr >> 16) &0xFF;
|
||||
leadOut.fr = (unsigned char)(toc.tracks[endTrack].lAddr >> 24) &0xFF;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
bool CDROM_Interface_Aspi::GetAudioTrackInfo (int track, TMSF& start, unsigned char& attr)
|
||||
{
|
||||
TOC toc;
|
||||
if (GetTOC((LPTOC)&toc) == SS_COMP) {
|
||||
start.min = (unsigned char)(toc.tracks[track-1].lAddr >> 8) &0xFF;
|
||||
start.sec = (unsigned char)(toc.tracks[track-1].lAddr >> 16) &0xFF;
|
||||
start.fr = (unsigned char)(toc.tracks[track-1].lAddr >> 24) &0xFF;
|
||||
attr = toc.tracks[track-1].cAdrCtrl;
|
||||
return true;
|
||||
};
|
||||
return false;
|
||||
};
|
||||
|
||||
HANDLE CDROM_Interface_Aspi::OpenIOCTLFile(char cLetter,BOOL bAsync)
|
||||
{
|
||||
HANDLE hF;
|
||||
char szFName[16];
|
||||
OSVERSIONINFO ov;
|
||||
DWORD dwFlags;
|
||||
DWORD dwIOCTLAttr;
|
||||
// if(bAsync) dwIOCTLAttr=FILE_FLAG_OVERLAPPED;
|
||||
// else
|
||||
dwIOCTLAttr=0;
|
||||
|
||||
memset(&ov,0,sizeof(OSVERSIONINFO));
|
||||
ov.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
|
||||
GetVersionEx(&ov);
|
||||
|
||||
if ((ov.dwPlatformId==VER_PLATFORM_WIN32_NT) && (ov.dwMajorVersion>4))
|
||||
dwFlags = GENERIC_READ|GENERIC_WRITE; // add gen write on W2k/XP
|
||||
else
|
||||
dwFlags = GENERIC_READ;
|
||||
|
||||
wsprintf(szFName, "\\\\.\\%c:",cLetter);
|
||||
|
||||
hF=CreateFile(szFName,dwFlags,FILE_SHARE_READ, // open drive
|
||||
NULL,OPEN_EXISTING,dwIOCTLAttr,NULL);
|
||||
|
||||
if (hF==INVALID_HANDLE_VALUE) {
|
||||
dwFlags^=GENERIC_WRITE; // mmm... no success
|
||||
hF=CreateFile(szFName,dwFlags,FILE_SHARE_READ, // -> open drive again
|
||||
NULL,OPEN_EXISTING,dwIOCTLAttr,NULL);
|
||||
if (hF==INVALID_HANDLE_VALUE) return NULL;
|
||||
}
|
||||
return hF;
|
||||
}
|
||||
|
||||
void CDROM_Interface_Aspi::GetIOCTLAdapter(HANDLE hF,int * iDA,int * iDT,int * iDL)
|
||||
{
|
||||
char szBuf[1024];
|
||||
PSCSI_ADDRESS pSA;
|
||||
DWORD dwRet;
|
||||
|
||||
*iDA=*iDT=*iDL=-1;
|
||||
if(hF==NULL) return;
|
||||
|
||||
memset(szBuf,0,1024);
|
||||
|
||||
pSA=(PSCSI_ADDRESS)szBuf;
|
||||
pSA->Length=sizeof(SCSI_ADDRESS);
|
||||
|
||||
if(!DeviceIoControl(hF,IOCTL_SCSI_GET_ADDRESS,NULL,
|
||||
0,pSA,sizeof(SCSI_ADDRESS),
|
||||
&dwRet,NULL))
|
||||
return;
|
||||
|
||||
*iDA = pSA->PortNumber;
|
||||
*iDT = pSA->TargetId;
|
||||
*iDL = pSA->Lun;
|
||||
}
|
||||
|
||||
DWORD CDROM_Interface_Aspi::GetTOC(LPTOC toc)
|
||||
{
|
||||
SRB_ExecSCSICmd s;DWORD dwStatus;
|
||||
|
||||
hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
||||
|
||||
memset(&s,0,sizeof(s));
|
||||
|
||||
s.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
||||
s.SRB_HaId = haId;
|
||||
s.SRB_Target = target;
|
||||
s.SRB_Lun = lun;
|
||||
s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
||||
s.SRB_BufLen = sizeof(*toc);
|
||||
s.SRB_BufPointer = (BYTE FAR *)toc;
|
||||
s.SRB_SenseLen = SENSE_LEN;
|
||||
s.SRB_CDBLen = 0x0A;
|
||||
s.SRB_PostProc = (LPVOID)hEvent;
|
||||
s.CDBByte[0] = SCSI_READ_TOC;
|
||||
s.CDBByte[1] = 0x02; // 0x02 for MSF
|
||||
s.CDBByte[7] = 0x03;
|
||||
s.CDBByte[8] = 0x24;
|
||||
|
||||
ResetEvent(hEvent);
|
||||
dwStatus=pSendASPI32Command((LPSRB)&s);
|
||||
|
||||
if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,30000);
|
||||
|
||||
CloseHandle(hEvent);
|
||||
|
||||
return (s.SRB_Status==SS_COMP);
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Aspi::PlayAudioSector(unsigned long start,unsigned long len)
|
||||
{
|
||||
SRB_ExecSCSICmd s;DWORD dwStatus;
|
||||
|
||||
hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
||||
|
||||
memset(&s,0,sizeof(s));
|
||||
s.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
||||
s.SRB_HaId = haId;
|
||||
s.SRB_Target = target;
|
||||
s.SRB_Lun = lun;
|
||||
s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
||||
s.SRB_BufLen = 0;
|
||||
s.SRB_BufPointer = 0;
|
||||
s.SRB_SenseLen = SENSE_LEN;
|
||||
s.SRB_CDBLen = 12;
|
||||
s.SRB_PostProc = (LPVOID)hEvent;
|
||||
|
||||
s.CDBByte[0] = SCSI_PLAYAUD_12;
|
||||
s.CDBByte[1] = lun << 5;
|
||||
s.CDBByte[2] = (unsigned char)((start >> 24) & 0xFF);
|
||||
s.CDBByte[3] = (unsigned char)((start >> 16) & 0xFF);
|
||||
s.CDBByte[4] = (unsigned char)((start >> 8) & 0xFF);
|
||||
s.CDBByte[5] = (unsigned char)((start & 0xFF));
|
||||
s.CDBByte[6] = (unsigned char)((len >> 24) & 0xFF);
|
||||
s.CDBByte[7] = (unsigned char)((len >> 16) & 0xFF);
|
||||
s.CDBByte[8] = (unsigned char)((len >> 8) & 0xFF);
|
||||
s.CDBByte[9] = (unsigned char)(len & 0xFF);
|
||||
|
||||
ResetEvent(hEvent);
|
||||
|
||||
dwStatus = pSendASPI32Command((LPSRB)&s);
|
||||
|
||||
if(dwStatus==SS_PENDING) WaitForSingleObject(hEvent,10000);
|
||||
|
||||
CloseHandle(hEvent);
|
||||
|
||||
return s.SRB_Status==SS_COMP;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Aspi::StopAudio(void)
|
||||
{
|
||||
return PauseAudio(false);
|
||||
};
|
||||
|
||||
bool CDROM_Interface_Aspi::PauseAudio(bool resume)
|
||||
{
|
||||
SRB_ExecSCSICmd s;DWORD dwStatus;
|
||||
|
||||
hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
||||
|
||||
memset(&s,0,sizeof(s));
|
||||
|
||||
s.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
||||
s.SRB_HaId = haId;
|
||||
s.SRB_Target = target;
|
||||
s.SRB_Lun = lun;
|
||||
s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
||||
s.SRB_BufLen = 0x00;
|
||||
s.SRB_SenseLen = SENSE_LEN;
|
||||
s.SRB_CDBLen = 0x0A;
|
||||
s.SRB_PostProc = (LPVOID)hEvent;
|
||||
s.CDBByte[0] = 0x4B;
|
||||
s.CDBByte[8] = (unsigned char)resume; // Pause
|
||||
|
||||
ResetEvent(hEvent);
|
||||
dwStatus=pSendASPI32Command((LPSRB)&s);
|
||||
|
||||
if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,30000);
|
||||
|
||||
CloseHandle(hEvent);
|
||||
|
||||
return (s.SRB_Status==SS_COMP);
|
||||
};
|
||||
|
||||
bool CDROM_Interface_Aspi::GetAudioSub(unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos)
|
||||
{
|
||||
SUB_Q_CURRENT_POSITION pos;
|
||||
SRB_ExecSCSICmd s;DWORD dwStatus;
|
||||
|
||||
hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
||||
|
||||
memset(&s,0,sizeof(s));
|
||||
|
||||
s.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
||||
s.SRB_HaId = haId;
|
||||
s.SRB_Target = target;
|
||||
s.SRB_Lun = lun;
|
||||
s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
||||
s.SRB_SenseLen = SENSE_LEN;
|
||||
|
||||
s.SRB_BufLen = sizeof(pos);
|
||||
s.SRB_BufPointer = (BYTE FAR *)&pos;
|
||||
s.SRB_CDBLen = 10;
|
||||
s.SRB_PostProc = (LPVOID)hEvent;
|
||||
|
||||
s.CDBByte[0] = SCSI_SUBCHANNEL;
|
||||
s.CDBByte[1] = (lun<<5)|2; // lun & msf
|
||||
s.CDBByte[2] = 0x40; // subq
|
||||
s.CDBByte[3] = 0x01; // curr pos info
|
||||
s.CDBByte[6] = 0; // track number (only in isrc mode, ignored)
|
||||
s.CDBByte[7] = 0; // alloc len
|
||||
s.CDBByte[8] = sizeof(pos);
|
||||
|
||||
ResetEvent(hEvent);
|
||||
|
||||
dwStatus = pSendASPI32Command((LPSRB)&s);
|
||||
|
||||
if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,0xFFFFFFFF);
|
||||
|
||||
CloseHandle(hEvent);
|
||||
|
||||
if (s.SRB_Status!=SS_COMP) return false;
|
||||
|
||||
attr = (pos.ADR<<4) | pos.Control;
|
||||
track = pos.TrackNumber;
|
||||
index = pos.IndexNumber;
|
||||
absPos.min = pos.AbsoluteAddress[1];
|
||||
absPos.sec = pos.AbsoluteAddress[2];
|
||||
absPos.fr = pos.AbsoluteAddress[3];
|
||||
relPos.min = pos.TrackRelativeAddress[1];
|
||||
relPos.sec = pos.TrackRelativeAddress[2];
|
||||
relPos.fr = pos.TrackRelativeAddress[3];
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
bool CDROM_Interface_Aspi::GetUPC(unsigned char& attr, char* upcdata)
|
||||
{
|
||||
SUB_Q_MEDIA_CATALOG_NUMBER upc;
|
||||
SRB_ExecSCSICmd s;DWORD dwStatus;
|
||||
|
||||
hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
||||
|
||||
memset(&s,0,sizeof(s));
|
||||
|
||||
s.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
||||
s.SRB_HaId = haId;
|
||||
s.SRB_Target = target;
|
||||
s.SRB_Lun = lun;
|
||||
s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
||||
s.SRB_SenseLen = SENSE_LEN;
|
||||
|
||||
s.SRB_BufLen = sizeof(upc);
|
||||
s.SRB_BufPointer = (BYTE FAR *)&upc;
|
||||
s.SRB_CDBLen = 10;
|
||||
s.SRB_PostProc = (LPVOID)hEvent;
|
||||
|
||||
s.CDBByte[0] = SCSI_SUBCHANNEL;
|
||||
s.CDBByte[1] = (lun<<5)|2; // lun & msf
|
||||
s.CDBByte[2] = 0x40; // subq
|
||||
s.CDBByte[3] = 0x02; // get upc
|
||||
s.CDBByte[6] = 0; // track number (only in isrc mode, ignored)
|
||||
s.CDBByte[7] = 0; // alloc len
|
||||
s.CDBByte[8] = sizeof(upc);
|
||||
|
||||
ResetEvent(hEvent);
|
||||
|
||||
dwStatus = pSendASPI32Command((LPSRB)&s);
|
||||
|
||||
if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,0xFFFFFFFF);
|
||||
|
||||
CloseHandle(hEvent);
|
||||
|
||||
if (s.SRB_Status!=SS_COMP) return false;
|
||||
|
||||
// attr = (upc.ADR<<4) | upc.Control;
|
||||
attr = 0;
|
||||
int pos = 0;
|
||||
// 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];
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
bool CDROM_Interface_Aspi::GetAudioStatus(bool& playing, bool& pause)
|
||||
{
|
||||
playing = pause = false;
|
||||
|
||||
SUB_Q_HEADER sub;
|
||||
SRB_ExecSCSICmd s;DWORD dwStatus;
|
||||
|
||||
hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
||||
|
||||
memset(&s,0,sizeof(s));
|
||||
|
||||
s.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
||||
s.SRB_HaId = haId;
|
||||
s.SRB_Target = target;
|
||||
s.SRB_Lun = lun;
|
||||
s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
||||
s.SRB_SenseLen = SENSE_LEN;
|
||||
|
||||
s.SRB_BufLen = sizeof(sub);
|
||||
s.SRB_BufPointer = (BYTE FAR *)⊂
|
||||
s.SRB_CDBLen = 10;
|
||||
s.SRB_PostProc = (LPVOID)hEvent;
|
||||
|
||||
s.CDBByte[0] = SCSI_SUBCHANNEL;
|
||||
s.CDBByte[1] = (lun<<5)|2; // lun & msf
|
||||
s.CDBByte[2] = 0x00; // no subq
|
||||
s.CDBByte[3] = 0x00; // dont care
|
||||
s.CDBByte[6] = 0; // track number (only in isrc mode, ignored)
|
||||
s.CDBByte[7] = 0; // alloc len
|
||||
s.CDBByte[8] = sizeof(sub);
|
||||
|
||||
ResetEvent(hEvent);
|
||||
|
||||
dwStatus = pSendASPI32Command((LPSRB)&s);
|
||||
|
||||
if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,0xFFFFFFFF);
|
||||
|
||||
CloseHandle(hEvent);
|
||||
|
||||
if (s.SRB_Status!=SS_COMP) return false;
|
||||
|
||||
playing = (sub.AudioStatus==0x11);
|
||||
pause = (sub.AudioStatus==0x12);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
bool CDROM_Interface_Aspi::LoadUnloadMedia(bool unload)
|
||||
{
|
||||
SRB_ExecSCSICmd s;DWORD dwStatus;
|
||||
|
||||
hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
||||
|
||||
memset(&s,0,sizeof(s));
|
||||
|
||||
s.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
||||
s.SRB_HaId = haId;
|
||||
s.SRB_Target = target;
|
||||
s.SRB_Lun = lun;
|
||||
s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
||||
s.SRB_SenseLen = SENSE_LEN;
|
||||
|
||||
s.SRB_BufLen = 0;
|
||||
s.SRB_BufPointer = 0;
|
||||
s.SRB_CDBLen = 14;
|
||||
s.SRB_PostProc = (LPVOID)hEvent;
|
||||
|
||||
s.CDBByte[0] = SCSI_LOAD_UN;
|
||||
s.CDBByte[1] = (lun<<5)|1; // lun & immediate
|
||||
s.CDBByte[4] = (unload ? 0x02:0x03); // unload/load media
|
||||
|
||||
ResetEvent(hEvent);
|
||||
|
||||
dwStatus = pSendASPI32Command((LPSRB)&s);
|
||||
|
||||
if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,0xFFFFFFFF);
|
||||
|
||||
CloseHandle(hEvent);
|
||||
|
||||
if (s.SRB_Status!=SS_COMP) return false;
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
bool CDROM_Interface_Aspi::GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen)
|
||||
{
|
||||
// Seems not possible to get this values using ioctl...
|
||||
int track1,track2;
|
||||
TMSF leadOut;
|
||||
// If we can read, there's a media
|
||||
mediaPresent = GetAudioTracks(track1, track2, leadOut),
|
||||
trayOpen = !mediaPresent;
|
||||
mediaChanged = (oldLeadOut.min!=leadOut.min) || (oldLeadOut.sec!=leadOut.sec) || (oldLeadOut.fr!=leadOut.fr);
|
||||
// Save old values
|
||||
oldLeadOut.min = leadOut.min;
|
||||
oldLeadOut.sec = leadOut.sec;
|
||||
oldLeadOut.fr = leadOut.fr;
|
||||
// always success
|
||||
return true;
|
||||
};
|
||||
|
||||
bool CDROM_Interface_Aspi::ReadSectors(void* buffer, bool raw, unsigned long sector, unsigned long num)
|
||||
{
|
||||
SRB_ExecSCSICmd s;DWORD dwStatus;
|
||||
|
||||
hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
|
||||
|
||||
memset(&s,0,sizeof(s));
|
||||
|
||||
// FIXME : Is there a method to get cooked sectors with aspi ???
|
||||
// all combination i tried were failing.
|
||||
// so we have to allocate extra mem and copy data to buffer if in cooked mode
|
||||
char* inPtr = (char*)buffer;
|
||||
if (!raw) inPtr = new char[num*2352];
|
||||
if (!inPtr) return false;
|
||||
|
||||
s.SRB_Cmd = SC_EXEC_SCSI_CMD;
|
||||
s.SRB_HaId = haId;
|
||||
s.SRB_Target = target;
|
||||
s.SRB_Lun = lun;
|
||||
s.SRB_Flags = SRB_DIR_IN | SRB_EVENT_NOTIFY;
|
||||
s.SRB_SenseLen = SENSE_LEN;
|
||||
|
||||
s.SRB_BufLen = 2352*num; //num*(raw?2352:2048);
|
||||
s.SRB_BufPointer = (BYTE FAR*)inPtr;
|
||||
s.SRB_CDBLen = 12;
|
||||
s.SRB_PostProc = (LPVOID)hEvent;
|
||||
|
||||
s.CDBByte[0] = 0xBE;
|
||||
s.CDBByte[2] = (unsigned char)((sector >> 24) & 0xFF);
|
||||
s.CDBByte[3] = (unsigned char)((sector >> 16) & 0xFF);
|
||||
s.CDBByte[4] = (unsigned char)((sector >> 8) & 0xFF);
|
||||
s.CDBByte[5] = (unsigned char)((sector & 0xFF));
|
||||
s.CDBByte[6] = (unsigned char)((num >> 16) & 0xFF);
|
||||
s.CDBByte[7] = (unsigned char)((num >> 8) & 0xFF);
|
||||
s.CDBByte[8] = (unsigned char) (num & 0xFF);
|
||||
s.CDBByte[9] = (raw?0xF0:0x10);
|
||||
|
||||
ResetEvent(hEvent);
|
||||
|
||||
dwStatus = pSendASPI32Command((LPSRB)&s);
|
||||
|
||||
if (dwStatus==SS_PENDING) WaitForSingleObject(hEvent,0xFFFFFFFF);
|
||||
|
||||
CloseHandle(hEvent);
|
||||
|
||||
if (s.SRB_Status!=SS_COMP) {
|
||||
if (!raw) delete[] inPtr;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!raw) {
|
||||
// copy user data to buffer
|
||||
char* source = inPtr;
|
||||
source+=16; // jump 16 bytes
|
||||
char* outPtr = (char*)buffer;
|
||||
for (unsigned long i=0; i<num; i++) {
|
||||
memcpy(outPtr,source,2048);
|
||||
outPtr+=COOKED_SECTOR_SIZE;
|
||||
source+=RAW_SECTOR_SIZE;
|
||||
};
|
||||
delete[] inPtr;
|
||||
};
|
||||
return true;
|
||||
};
|
||||
|
||||
#endif
|
275
src/dos/cdrom_ioctl_win32.cpp
Normal file
275
src/dos/cdrom_ioctl_win32.cpp
Normal file
@ -0,0 +1,275 @@
|
||||
/*
|
||||
* Copyright (C) 2002-2003 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#if defined (WIN32)
|
||||
|
||||
// *****************************************************************
|
||||
// Windows IOCTL functions (not suitable for 95/98/Me)
|
||||
// *****************************************************************
|
||||
|
||||
#include <windows.h>
|
||||
#include <winioctl.h> // Ioctl stuff
|
||||
#include "ntddcdrm.h" // Ioctl stuff
|
||||
#include "cdrom.h"
|
||||
|
||||
CDROM_Interface_Ioctl::CDROM_Interface_Ioctl()
|
||||
{
|
||||
pathname[0] = 0;
|
||||
hIOCTL = INVALID_HANDLE_VALUE;
|
||||
memset(&oldLeadOut,0,sizeof(oldLeadOut));
|
||||
};
|
||||
|
||||
CDROM_Interface_Ioctl::~CDROM_Interface_Ioctl()
|
||||
{
|
||||
StopAudio();
|
||||
};
|
||||
|
||||
bool CDROM_Interface_Ioctl::GetUPC(unsigned char& attr, char* upc)
|
||||
{
|
||||
// FIXME : To Do
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Ioctl::GetAudioTracks(int& stTrack, int& endTrack, TMSF& leadOut)
|
||||
{
|
||||
Open();
|
||||
CDROM_TOC toc;
|
||||
DWORD byteCount;
|
||||
BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_TOC, NULL, 0,
|
||||
&toc, sizeof(toc), &byteCount,NULL);
|
||||
Close();
|
||||
if (!bStat) return false;
|
||||
|
||||
stTrack = toc.FirstTrack;
|
||||
endTrack = toc.LastTrack;
|
||||
leadOut.min = toc.TrackData[endTrack].Address[1];
|
||||
leadOut.sec = toc.TrackData[endTrack].Address[2];
|
||||
leadOut.fr = toc.TrackData[endTrack].Address[3];
|
||||
return true;
|
||||
};
|
||||
|
||||
bool CDROM_Interface_Ioctl::GetAudioTrackInfo(int track, TMSF& start, unsigned char& attr)
|
||||
{
|
||||
Open();
|
||||
CDROM_TOC toc;
|
||||
DWORD byteCount;
|
||||
BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_TOC, NULL, 0,
|
||||
&toc, sizeof(toc), &byteCount,NULL);
|
||||
Close();
|
||||
if (!bStat) return false;
|
||||
|
||||
attr = (toc.TrackData[track-1].Adr << 4) | toc.TrackData[track].Control;
|
||||
start.min = toc.TrackData[track-1].Address[1];
|
||||
start.sec = toc.TrackData[track-1].Address[2];
|
||||
start.fr = toc.TrackData[track-1].Address[3];
|
||||
return true;
|
||||
};
|
||||
|
||||
bool CDROM_Interface_Ioctl::GetAudioSub(unsigned char& attr, unsigned char& track, unsigned char& index, TMSF& relPos, TMSF& absPos)
|
||||
{
|
||||
Open();
|
||||
|
||||
CDROM_SUB_Q_DATA_FORMAT insub;
|
||||
SUB_Q_CHANNEL_DATA sub;
|
||||
DWORD byteCount;
|
||||
|
||||
insub.Format = IOCTL_CDROM_CURRENT_POSITION;
|
||||
|
||||
BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL, &insub, sizeof(insub),
|
||||
&sub, sizeof(sub), &byteCount,NULL);
|
||||
Close();
|
||||
if (!bStat) return false;
|
||||
|
||||
attr = (sub.CurrentPosition.ADR << 4) | sub.CurrentPosition.Control;
|
||||
track = sub.CurrentPosition.TrackNumber;
|
||||
index = sub.CurrentPosition.IndexNumber;
|
||||
relPos.min = sub.CurrentPosition.TrackRelativeAddress[1];
|
||||
relPos.sec = sub.CurrentPosition.TrackRelativeAddress[2];
|
||||
relPos.fr = sub.CurrentPosition.TrackRelativeAddress[3];
|
||||
absPos.min = sub.CurrentPosition.AbsoluteAddress[1];
|
||||
absPos.sec = sub.CurrentPosition.AbsoluteAddress[2];
|
||||
absPos.fr = sub.CurrentPosition.AbsoluteAddress[3];
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
bool CDROM_Interface_Ioctl::GetAudioStatus(bool& playing, bool& pause)
|
||||
{
|
||||
Open();
|
||||
|
||||
CDROM_SUB_Q_DATA_FORMAT insub;
|
||||
SUB_Q_CHANNEL_DATA sub;
|
||||
DWORD byteCount;
|
||||
|
||||
insub.Format = IOCTL_CDROM_CURRENT_POSITION;
|
||||
|
||||
BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL, &insub, sizeof(insub),
|
||||
&sub, sizeof(sub), &byteCount,NULL);
|
||||
Close();
|
||||
if (!bStat) return false;
|
||||
|
||||
playing = (sub.CurrentPosition.Header.AudioStatus == AUDIO_STATUS_IN_PROGRESS);
|
||||
pause = (sub.CurrentPosition.Header.AudioStatus == AUDIO_STATUS_PAUSED);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
bool CDROM_Interface_Ioctl::GetMediaTrayStatus(bool& mediaPresent, bool& mediaChanged, bool& trayOpen)
|
||||
{
|
||||
// Seems not possible to get this values using ioctl...
|
||||
int track1,track2;
|
||||
TMSF leadOut;
|
||||
// If we can read, there's a media
|
||||
mediaPresent = GetAudioTracks(track1, track2, leadOut),
|
||||
trayOpen = !mediaPresent;
|
||||
mediaChanged = (oldLeadOut.min!=leadOut.min) || (oldLeadOut.sec!=leadOut.sec) || (oldLeadOut.fr!=leadOut.fr);
|
||||
// Save old values
|
||||
oldLeadOut.min = leadOut.min;
|
||||
oldLeadOut.sec = leadOut.sec;
|
||||
oldLeadOut.fr = leadOut.fr;
|
||||
// always success
|
||||
return true;
|
||||
};
|
||||
|
||||
bool CDROM_Interface_Ioctl::PlayAudioSector (unsigned long start,unsigned long len)
|
||||
{
|
||||
Open();
|
||||
CDROM_PLAY_AUDIO_MSF audio;
|
||||
DWORD byteCount;
|
||||
// Start
|
||||
unsigned long addr = start + 150;
|
||||
audio.StartingF = (UCHAR)(addr%75); addr/=75;
|
||||
audio.StartingS = (UCHAR)(addr%60);
|
||||
audio.StartingM = (UCHAR)(addr/60);
|
||||
// End
|
||||
addr = start + len + 150;
|
||||
audio.EndingF = (UCHAR)(addr%75); addr/=75;
|
||||
audio.EndingS = (UCHAR)(addr%60);
|
||||
audio.EndingM = (UCHAR)(addr/60);
|
||||
|
||||
BOOL bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_PLAY_AUDIO_MSF, &audio, sizeof(audio),
|
||||
NULL, 0, &byteCount,NULL);
|
||||
Close();
|
||||
return bStat>0;
|
||||
};
|
||||
|
||||
bool CDROM_Interface_Ioctl::PauseAudio(bool resume)
|
||||
{
|
||||
Open();
|
||||
BOOL bStat;
|
||||
DWORD byteCount;
|
||||
if (resume) bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_RESUME_AUDIO, NULL, 0,
|
||||
NULL, 0, &byteCount,NULL);
|
||||
else bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_PAUSE_AUDIO, NULL, 0,
|
||||
NULL, 0, &byteCount,NULL);
|
||||
Close();
|
||||
return bStat>0;
|
||||
};
|
||||
|
||||
bool CDROM_Interface_Ioctl::StopAudio(void)
|
||||
{
|
||||
Open();
|
||||
BOOL bStat;
|
||||
DWORD byteCount;
|
||||
bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_STOP_AUDIO, NULL, 0,
|
||||
NULL, 0, &byteCount,NULL);
|
||||
Close();
|
||||
return bStat>0;
|
||||
};
|
||||
|
||||
bool CDROM_Interface_Ioctl::LoadUnloadMedia(bool unload)
|
||||
{
|
||||
Open();
|
||||
BOOL bStat;
|
||||
DWORD byteCount;
|
||||
if (unload) bStat = DeviceIoControl(hIOCTL,IOCTL_STORAGE_EJECT_MEDIA, NULL, 0,
|
||||
NULL, 0, &byteCount,NULL);
|
||||
else bStat = DeviceIoControl(hIOCTL,IOCTL_STORAGE_LOAD_MEDIA, NULL, 0,
|
||||
NULL, 0, &byteCount,NULL);
|
||||
Close();
|
||||
return bStat>0;
|
||||
};
|
||||
|
||||
bool CDROM_Interface_Ioctl::ReadSectors(void* buffer, bool raw, unsigned long sector, unsigned long num)
|
||||
{
|
||||
// TODO : How to copy cooked without current overhead ?
|
||||
BOOL bStat;
|
||||
DWORD byteCount;
|
||||
RAW_READ_INFO in;
|
||||
char* inPtr;
|
||||
|
||||
in.DiskOffset.LowPart = sector;
|
||||
in.DiskOffset.HighPart = 0;
|
||||
in.SectorCount = num;
|
||||
in.TrackMode = CDDA;
|
||||
|
||||
if (!raw) inPtr = new char[num*RAW_SECTOR_SIZE];
|
||||
else inPtr = (char*)buffer;
|
||||
|
||||
bStat = DeviceIoControl(hIOCTL,IOCTL_CDROM_RAW_READ, &in, sizeof(in),
|
||||
inPtr, num*RAW_SECTOR_SIZE, &byteCount,NULL);
|
||||
|
||||
if (!raw) {
|
||||
char* source = inPtr;
|
||||
source+=16; // jump 16 bytes
|
||||
char* outPtr = (char*)buffer;
|
||||
for (unsigned long i=0; i<num; i++) {
|
||||
memcpy(outPtr,source,COOKED_SECTOR_SIZE);
|
||||
outPtr+=COOKED_SECTOR_SIZE;
|
||||
source+=RAW_SECTOR_SIZE;
|
||||
};
|
||||
delete[] inPtr;
|
||||
};
|
||||
|
||||
return (byteCount!=num*RAW_SECTOR_SIZE) && (bStat>0);
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Ioctl::SetDevice(char* path, int forceCD)
|
||||
{
|
||||
if (GetDriveType(path)==DRIVE_CDROM) {
|
||||
char letter [3] = { 0, ':', 0 };
|
||||
letter[0] = path[0];
|
||||
strcpy(pathname,"\\\\.\\");
|
||||
strcat(pathname,letter);
|
||||
if (Open()) {
|
||||
Close();
|
||||
return true;
|
||||
};
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Ioctl::Open(void)
|
||||
{
|
||||
hIOCTL = CreateFile(pathname, // drive to open
|
||||
GENERIC_READ, // read access
|
||||
FILE_SHARE_READ | // share mode
|
||||
FILE_SHARE_WRITE,
|
||||
NULL, // default security attributes
|
||||
OPEN_EXISTING, // disposition
|
||||
0, // file attributes
|
||||
NULL); // do not copy file attributes
|
||||
return (hIOCTL!=INVALID_HANDLE_VALUE);
|
||||
};
|
||||
|
||||
void CDROM_Interface_Ioctl::Close(void)
|
||||
{
|
||||
CloseHandle(hIOCTL);
|
||||
};
|
||||
|
||||
#endif
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2002 The DOSBox Team
|
||||
* Copyright (C) 2002-2003 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -120,7 +120,7 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) {
|
||||
ansi.esc=true;
|
||||
count++;
|
||||
if(!ansiwarned) {
|
||||
LOG_WARN("ANSI sequences detected. enabling ansi support"); /* maybe LOG_MSG */
|
||||
LOG(LOG_IOCTL,"ANSI sequences detected. enabling ansi support"); /* maybe LOG_MSG */
|
||||
ansiwarned=true;
|
||||
}
|
||||
continue;
|
||||
@ -143,7 +143,7 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) {
|
||||
case 'D':/* scrolling DOWN*/
|
||||
case 'M':/* scrolling UP*/
|
||||
default:
|
||||
LOG_DEBUG("ANSI: unknown char %c after a esc",data[count]); /*prob () */
|
||||
LOG(LOG_IOCTL,"ANSI: unknown char %c after a esc",data[count]); /*prob () */
|
||||
ClearAnsi();
|
||||
break;
|
||||
}
|
||||
@ -179,13 +179,13 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) {
|
||||
ansi.attr|=0x8;
|
||||
break;
|
||||
case 4: /* underline */
|
||||
LOG_DEBUG("ANSI:no support for underline yet");
|
||||
LOG(LOG_IOCTL,"ANSI:no support for underline yet");
|
||||
break;
|
||||
case 5: /* blinking */
|
||||
LOG_DEBUG("ANSI:no support for blinking yet");
|
||||
LOG(LOG_IOCTL,"ANSI:no support for blinking yet");
|
||||
break;
|
||||
case 7: /* reverse */
|
||||
LOG_DEBUG("ANSI:no support for reverse yet");
|
||||
LOG(LOG_IOCTL,"ANSI:no support for reverse yet");
|
||||
break;
|
||||
case 30: /* fg color black */
|
||||
ansi.attr&=0xf8;
|
||||
@ -284,7 +284,7 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) {
|
||||
case 'J': /*erase screen and move cursor home*/
|
||||
if(ansi.data[0]==0) ansi.data[0]=2;
|
||||
if(ansi.data[0]!=2) {/* only number 2 (the standard one supported) */
|
||||
LOG_DEBUG("ANSI: esc[%dJ called : not supported",ansi.data[0]);
|
||||
LOG(LOG_IOCTL,"ANSI: esc[%dJ called : not supported",ansi.data[0]);
|
||||
break;
|
||||
}
|
||||
for(i=0;i<(Bitu)ansi.ncols*ansi.nrows;i++) INT10_TeletypeOutput(' ',ansi.attr,true,0);
|
||||
@ -293,7 +293,7 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) {
|
||||
break;
|
||||
case 'h': /* set MODE (if code =7 enable linewrap) */
|
||||
case 'I': /*RESET MODE */
|
||||
LOG_DEBUG("ANSI: set/reset mode called(not supported)");
|
||||
LOG(LOG_IOCTL,"ANSI: set/reset mode called(not supported)");
|
||||
ClearAnsi();
|
||||
break;
|
||||
case 'D': /*Cursor Backward */
|
||||
@ -320,7 +320,7 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) {
|
||||
case 'p':/* reassign keys (needs strings) */
|
||||
case 'i':/* printer stuff */
|
||||
default:
|
||||
LOG_DEBUG("ANSI: unhandled char %c in esc[",data[count]);
|
||||
LOG(LOG_IOCTL,"ANSI: unhandled char %c in esc[",data[count]);
|
||||
ClearAnsi();
|
||||
break;
|
||||
}
|
||||
|
200
src/dos/dos.cpp
200
src/dos/dos.cpp
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2002 The DOSBox Team
|
||||
* Copyright (C) 2002-2003 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -27,12 +27,15 @@
|
||||
#include "callback.h"
|
||||
#include "regs.h"
|
||||
#include "dos_inc.h"
|
||||
#include "setup.h"
|
||||
#include "cpu.h"
|
||||
|
||||
DOS_Block dos;
|
||||
DOS_InfoBlock dos_infoblock;
|
||||
|
||||
Bit8u dos_copybuf[0x10000];
|
||||
static Bitu call_20,call_21,call_27,call_28,call_29;
|
||||
static Bitu call_20,call_21,call_25,call_26,call_27,call_28,call_29;
|
||||
static Bitu call_casemap;
|
||||
|
||||
void DOS_SetError(Bit16u code) {
|
||||
dos.errorcode=code;
|
||||
@ -130,8 +133,8 @@ static Bitu DOS_21Handler(void) {
|
||||
break;
|
||||
};
|
||||
case 0x0b: /* Get STDIN Status */
|
||||
if (DOS_GetSTDINStatus()) reg_al=0xff;
|
||||
else reg_al=0;
|
||||
if (!DOS_GetSTDINStatus()) {reg_al=0x00;}
|
||||
else {reg_al=0xFF;}
|
||||
break;
|
||||
case 0x0c: /* Flush Buffer and read STDIN call */
|
||||
{
|
||||
@ -169,7 +172,7 @@ static Bitu DOS_21Handler(void) {
|
||||
}else{
|
||||
reg_al=0xff;
|
||||
}
|
||||
LOG_DEBUG("DOS:0x0f FCB-fileopen used, result:al=%d",reg_al);
|
||||
LOG(LOG_FCB,"DOS:0x0f FCB-fileopen used, result:al=%d",reg_al);
|
||||
break;
|
||||
case 0x10: /* Close File using FCB */
|
||||
if(DOS_FCBClose(SegValue(ds),reg_dx)){
|
||||
@ -177,7 +180,7 @@ static Bitu DOS_21Handler(void) {
|
||||
}else{
|
||||
reg_al=0xff;
|
||||
}
|
||||
LOG_DEBUG("DOS:0x10 FCB-fileclose used, result:al=%d",reg_al);
|
||||
LOG(LOG_FCB,"DOS:0x10 FCB-fileclose used, result:al=%d",reg_al);
|
||||
break;
|
||||
case 0x11: /* Find First Matching File using FCB */
|
||||
if(DOS_FCBFindFirst(SegValue(ds),reg_dx)){
|
||||
@ -185,7 +188,7 @@ static Bitu DOS_21Handler(void) {
|
||||
}else{
|
||||
reg_al=0xff;
|
||||
}
|
||||
LOG_DEBUG("DOS:0x11 FCB-FindFirst used, result:al=%d",reg_al);
|
||||
LOG(LOG_FCB,"DOS:0x11 FCB-FindFirst used, result:al=%d",reg_al);
|
||||
break;
|
||||
case 0x12: /* Find Next Matching File using FCB */
|
||||
if(DOS_FCBFindNext(SegValue(ds),reg_dx)){
|
||||
@ -193,7 +196,7 @@ static Bitu DOS_21Handler(void) {
|
||||
}else{
|
||||
reg_al=0xff;
|
||||
}
|
||||
LOG_DEBUG("DOS:0x12 FCB-FindNext used, result:al=%d",reg_al);
|
||||
LOG(LOG_FCB,"DOS:0x12 FCB-FindNext used, result:al=%d",reg_al);
|
||||
break;
|
||||
case 0x13: /* Delete File using FCB */
|
||||
if (DOS_FCBDeleteFile(SegValue(ds),reg_dx)) reg_al = 0x00;
|
||||
@ -201,16 +204,16 @@ static Bitu DOS_21Handler(void) {
|
||||
break;
|
||||
case 0x14: /* Sequential read from FCB */
|
||||
reg_al = DOS_FCBRead(SegValue(ds),reg_dx,0);
|
||||
LOG_DEBUG("DOS:0x14 FCB-Read used, result:al=%d",reg_al);
|
||||
LOG(LOG_FCB,"DOS:0x14 FCB-Read used, result:al=%d",reg_al);
|
||||
break;
|
||||
case 0x15: /* Sequential write to FCB */
|
||||
reg_al=DOS_FCBWrite(SegValue(ds),reg_dx,0);
|
||||
LOG_DEBUG("DOS:0x15 FCB-Write used, result:al=%d",reg_al);
|
||||
LOG(LOG_FCB,"DOS:0x15 FCB-Write used, result:al=%d",reg_al);
|
||||
break;
|
||||
case 0x16: /* Create or truncate file using FCB */
|
||||
if (DOS_FCBCreate(SegValue(ds),reg_dx)) reg_al = 0x00;
|
||||
else reg_al = 0xFF;
|
||||
LOG_DEBUG("DOS:0x16 FCB-Create used, result:al=%d",reg_al);
|
||||
LOG(LOG_FCB,"DOS:0x16 FCB-Create used, result:al=%d",reg_al);
|
||||
break;
|
||||
case 0x17: /* Rename file using FCB */
|
||||
if (DOS_FCBRenameFile(SegValue(ds),reg_dx)) reg_al = 0x00;
|
||||
@ -224,11 +227,11 @@ static Bitu DOS_21Handler(void) {
|
||||
break;
|
||||
case 0x21: /* Read random record from FCB */
|
||||
reg_al = DOS_FCBRandomRead(SegValue(ds),reg_dx,1,true);
|
||||
LOG_DEBUG("DOS:0x21 FCB-Random read used, result:al=%d",reg_al);
|
||||
LOG(LOG_FCB,"DOS:0x21 FCB-Random read used, result:al=%d",reg_al);
|
||||
break;
|
||||
case 0x22: /* Write random record to FCB */
|
||||
reg_al=DOS_FCBRandomWrite(SegValue(ds),reg_dx,1,true);
|
||||
LOG_DEBUG("DOS:0x28 FCB-Random write used, result:al=%d",reg_al);
|
||||
LOG(LOG_FCB,"DOS:0x22 FCB-Random write used, result:al=%d",reg_al);
|
||||
break;
|
||||
case 0x23: /* Get file size for FCB */
|
||||
if (DOS_FCBGetFileSize(SegValue(ds),reg_dx,reg_cx)) reg_al = 0x00;
|
||||
@ -239,11 +242,11 @@ static Bitu DOS_21Handler(void) {
|
||||
break;
|
||||
case 0x27: /* Random block read from FCB */
|
||||
reg_al = DOS_FCBRandomRead(SegValue(ds),reg_dx,reg_cx,false);
|
||||
LOG_DEBUG("DOS:0x27 FCB-Random(block) read used, result:al=%d",reg_al);
|
||||
LOG(LOG_FCB,"DOS:0x27 FCB-Random(block) read used, result:al=%d",reg_al);
|
||||
break;
|
||||
case 0x28: /* Random Block write to FCB */
|
||||
reg_al=DOS_FCBRandomWrite(SegValue(ds),reg_dx,reg_cx,false);
|
||||
LOG_DEBUG("DOS:0x28 FCB-Random(block) write used, result:al=%d",reg_al);
|
||||
LOG(LOG_FCB,"DOS:0x28 FCB-Random(block) write used, result:al=%d",reg_al);
|
||||
break;
|
||||
case 0x29: /* Parse filename into FCB */
|
||||
{ Bit8u difference;
|
||||
@ -252,7 +255,7 @@ static Bitu DOS_21Handler(void) {
|
||||
reg_al=FCB_Parsename(SegValue(es),reg_di,reg_al ,string, &difference);
|
||||
reg_si+=difference;
|
||||
}
|
||||
LOG_DEBUG("DOS:29:FCB Parse Filename, result:al=%d",reg_al);
|
||||
LOG(LOG_FCB,"DOS:29:FCB Parse Filename, result:al=%d",reg_al);
|
||||
break;
|
||||
case 0x19: /* Get current default drive */
|
||||
reg_al=DOS_GetDefaultDrive();
|
||||
@ -264,11 +267,6 @@ static Bitu DOS_21Handler(void) {
|
||||
psp.SetDTA(dos.dta);
|
||||
}
|
||||
break;
|
||||
case 0x1f: /* Get drive parameter block for default drive */
|
||||
|
||||
case 0x32: /* Get drive parameter block for specific drive */
|
||||
E_Exit("DOS:Unhandled call %02X",reg_ah);
|
||||
break; /* TODO maybe but hardly think a game needs this */
|
||||
case 0x25: /* Set Interrupt Vector */
|
||||
RealSetVec(reg_al,RealMakeSeg(ds,reg_dx));
|
||||
break;
|
||||
@ -303,11 +301,11 @@ static Bitu DOS_21Handler(void) {
|
||||
reg_ch=(Bit8u)(seconds/3600);
|
||||
reg_cl=(Bit8u)((seconds % 3600)/60);
|
||||
reg_dh=(Bit8u)(seconds % 60);
|
||||
reg_dl=(Bit8u)((ticks % 20)*5); /* 0-19 ->0-95 */
|
||||
reg_dl=(Bit8u)(((ticks * 10) % 182)*100)/182;
|
||||
}
|
||||
break;
|
||||
case 0x2d: /* Set System Time */
|
||||
LOG_DEBUG("DOS:Set System Time not supported");
|
||||
LOG(LOG_ERROR,"DOS:Set System Time not supported");
|
||||
reg_al=0; /* Noone is changing system time */
|
||||
break;
|
||||
case 0x2e: /* Set Verify flag */
|
||||
@ -385,18 +383,29 @@ static Bitu DOS_21Handler(void) {
|
||||
case 3:
|
||||
reg_al=0;break;
|
||||
};
|
||||
LOG_DEBUG("DOS:0x37:Call for not supported switchchar");
|
||||
LOG(LOG_ERROR|LOG_MISC,"DOS:0x37:Call for not supported switchchar");
|
||||
break;
|
||||
case 0x38: /* Set Country Code */
|
||||
LOG_DEBUG("DOS:Setting country code not supported");
|
||||
CALLBACK_SCF(true);
|
||||
break;
|
||||
if (reg_al==0) { /* Get country specidic information */
|
||||
|
||||
PhysPt pt = SegPhys(ds)+reg_dx;
|
||||
mem_writew(pt ,0x00); // USA
|
||||
mem_writeb(pt+ 2, '$'); mem_writeb(pt+ 3,0x00);
|
||||
mem_writeb(pt+ 7, '.'); mem_writeb(pt+ 8,0x00);
|
||||
mem_writeb(pt+ 9, '.'); mem_writeb(pt+10,0x00);
|
||||
mem_writeb(pt+11, '.'); mem_writeb(pt+12,0x00);
|
||||
mem_writeb(pt+13, '.'); mem_writeb(pt+14,0x00);
|
||||
mem_writeb(pt+15,0x01); // currency format
|
||||
mem_writeb(pt+16,0x02); // num digits
|
||||
mem_writeb(pt+17,0x00); // time format
|
||||
mem_writed(pt+18,CALLBACK_RealPointer(call_casemap));
|
||||
mem_writew(pt+22,0x00); // data list seperator
|
||||
reg_bx = 0x01;
|
||||
CALLBACK_SCF(false);
|
||||
break;
|
||||
} else { /* Set country code */
|
||||
|
||||
|
||||
LOG(LOG_ERROR|LOG_MISC,"DOS:Setting country code not supported");
|
||||
}
|
||||
CALLBACK_SCF(true);
|
||||
break;
|
||||
case 0x39: /* MKDIR Create directory */
|
||||
MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF);
|
||||
@ -514,7 +523,7 @@ static Bitu DOS_21Handler(void) {
|
||||
}
|
||||
break;
|
||||
case 0x01: /* Set */
|
||||
LOG_DEBUG("DOS:Set File Attributes for %s not supported",name1);
|
||||
LOG(LOG_ERROR|LOG_MISC,"DOS:Set File Attributes for %s not supported",name1);
|
||||
CALLBACK_SCF(false);
|
||||
break;
|
||||
default:
|
||||
@ -591,7 +600,7 @@ static Bitu DOS_21Handler(void) {
|
||||
case 0x4b: /* EXEC Load and/or execute program */
|
||||
{
|
||||
MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF);
|
||||
LOG_DEBUG("Execute %s %d",name1,reg_al);
|
||||
LOG(LOG_ERROR|LOG_MISC,"Execute %s %d",name1,reg_al);
|
||||
if (!DOS_Execute(name1,SegPhys(es)+reg_bx,reg_al)) {
|
||||
reg_ax=dos.errorcode;
|
||||
CALLBACK_SCF(true);
|
||||
@ -645,7 +654,7 @@ static Bitu DOS_21Handler(void) {
|
||||
RealPt addr=dos_infoblock.GetPointer();
|
||||
SegSet16(es,RealSeg(addr));
|
||||
reg_bx=RealOff(addr);
|
||||
LOG_DEBUG("Call is made for list of lists - let's hope for the best");
|
||||
LOG(LOG_MISC,"Call is made for list of lists - let's hope for the best");
|
||||
break; }
|
||||
//TODO Think hard how shit this is gonna be
|
||||
//And will any game ever use this :)
|
||||
@ -679,19 +688,27 @@ static Bitu DOS_21Handler(void) {
|
||||
} else {
|
||||
reg_cx=0;
|
||||
reg_dx=0;
|
||||
LOG_DEBUG("DOS:57:Setting File Date is faked",reg_ah);
|
||||
LOG(LOG_ERROR|LOG_MISC,"DOS:57:Setting File Date is faked",reg_ah);
|
||||
}
|
||||
break;
|
||||
case 0x58: /* Get/Set Memory allocation strategy */
|
||||
switch (reg_al) {
|
||||
case 0: /* Get Strategy */
|
||||
case 0: /* Get Strategy */
|
||||
reg_ax=DOS_GetMemAllocStrategy();
|
||||
break;
|
||||
case 1: /* Set Strategy */
|
||||
case 1: /* Set Strategy */
|
||||
DOS_SetMemAllocStrategy(reg_bx);
|
||||
break;
|
||||
case 2: /* Get UMB Link Status */
|
||||
reg_ax=1; // no UMB support
|
||||
CALLBACK_SCF(true);
|
||||
break;
|
||||
case 3: /* Set UMB Link Status */
|
||||
reg_ax=1; // failure, no support
|
||||
CALLBACK_SCF(true);
|
||||
break;
|
||||
default:
|
||||
LOG_DEBUG("DOS:58:Not Supported Set//Get memory allocation call %X",reg_al);
|
||||
LOG(LOG_ERROR|LOG_MISC,"DOS:58:Not Supported Set//Get memory allocation call %X",reg_al);
|
||||
}
|
||||
break;
|
||||
case 0x59: /* Get Extended error information */
|
||||
@ -733,12 +750,6 @@ static Bitu DOS_21Handler(void) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x5c: /* FLOCK File region locking */
|
||||
case 0x5e: /* More Network Functions */
|
||||
case 0x5f: /* And Even More Network Functions */
|
||||
E_Exit("DOS:Unhandled call %02X",reg_ah);
|
||||
break;
|
||||
case 0x60: /* Canonicalize filename or path */
|
||||
MEM_StrCopy(SegPhys(ds)+reg_dx,name1,DOSNAMEBUF);
|
||||
if (DOS_Canonicalize(name1,name2)) {
|
||||
@ -758,7 +769,7 @@ static Bitu DOS_21Handler(void) {
|
||||
case 0x65: /* Get extented country information and a lot of other useless shit*/
|
||||
/* Todo maybe fully support this for now we set it standard for USA */
|
||||
{
|
||||
LOG_DEBUG("DOS:65:Extended country information call");
|
||||
LOG(LOG_ERROR|LOG_MISC,"DOS:65:Extended country information call");
|
||||
PhysPt data=SegPhys(es)+reg_di;
|
||||
switch (reg_al) {
|
||||
case 1:
|
||||
@ -769,34 +780,48 @@ static Bitu DOS_21Handler(void) {
|
||||
reg_cx=4;
|
||||
CALLBACK_SCF(false);
|
||||
break;
|
||||
default:
|
||||
case 2: // Get pointer to uppercase table
|
||||
case 3: // Get pointer to lowercase table
|
||||
case 4: // Get pointer to filename uppercase table
|
||||
case 5: // Get pointer to filename terminator table
|
||||
case 6: // Get pointer to collating sequence table
|
||||
case 7: // Get pointer to double byte char set table
|
||||
mem_writew(data ,0x0000); // We dont have this table...
|
||||
mem_writew(data+2,0x0000); // End of table
|
||||
reg_cx=4;
|
||||
CALLBACK_SCF(false);
|
||||
break;
|
||||
default:
|
||||
E_Exit("DOS:0x65:Unhandled country information call %2X",reg_al);
|
||||
};
|
||||
break;
|
||||
}
|
||||
case 0x66: /* Get/Set global code page table */
|
||||
if (reg_al==1) {
|
||||
LOG_DEBUG("Getting global code page table");
|
||||
LOG(LOG_ERROR|LOG_MISC,"Getting global code page table");
|
||||
reg_bx=reg_dx=437;
|
||||
CALLBACK_SCF(false);
|
||||
break;
|
||||
}
|
||||
LOG_ERROR("DOS:Setting code page table is not supported");
|
||||
LOG(LOG_DOSMISC,"DOS:Setting code page table is not supported");
|
||||
break;
|
||||
case 0x67: /* Set handle countr */
|
||||
case 0x67: /* Set handle count */
|
||||
/* Weird call to increase amount of file handles needs to allocate memory if >20 */
|
||||
LOG_DEBUG("DOS:67:Set Handle Count not working");
|
||||
CALLBACK_SCF(false);
|
||||
break;
|
||||
{
|
||||
DOS_PSP psp(dos.psp);
|
||||
psp.SetNumFiles(reg_bx);
|
||||
CALLBACK_SCF(false);
|
||||
break;
|
||||
};
|
||||
case 0x69: /* Get/Set disk serial number */
|
||||
{
|
||||
switch(reg_al) {
|
||||
case 0x00: /* Get */
|
||||
LOG_DEBUG("DOS:Get Disk serial number");
|
||||
LOG(LOG_ERROR|LOG_MISC,"DOS:Get Disk serial number");
|
||||
CALLBACK_SCF(true);
|
||||
break;
|
||||
case 0x01:
|
||||
LOG_DEBUG("DOS:Set Disk serial number");
|
||||
LOG(LOG_ERROR|LOG_MISC,"DOS:Set Disk serial number");
|
||||
default:
|
||||
E_Exit("DOS:Illegal Get Serial Number call %2X",reg_al);
|
||||
}
|
||||
@ -808,7 +833,7 @@ static Bitu DOS_21Handler(void) {
|
||||
case 0x71: /* Unknown probably 4dos detection */
|
||||
reg_ax=0x7100;
|
||||
CALLBACK_SCF(true);
|
||||
LOG_WARN("DOS:Windows long file name support call %2X",reg_al);
|
||||
LOG(LOG_DOSMISC,"DOS:Windows long file name support call %2X",reg_al);
|
||||
break;
|
||||
case 0x68: /* FFLUSH Commit file */
|
||||
case 0x63: /* Weirdo double byte stuff (fails but say it succeeded) available only in MSDOS 2.25 */
|
||||
@ -821,9 +846,15 @@ static Bitu DOS_21Handler(void) {
|
||||
case 0x6b: /* NULL Function */
|
||||
case 0x61: /* UNUSED */
|
||||
case 0xEF: /* Used in Ancient Art Of War CGA */
|
||||
case 0x5d: /* Network Functions */
|
||||
default:
|
||||
LOG_DEBUG("DOS:Unhandled call %02X al=%02X. Set al to default of 0",reg_ah,reg_al);
|
||||
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 0x32: /* Get drive parameter block for specific drive */
|
||||
case 0x5c: /* FLOCK File region locking */
|
||||
case 0x5e: /* More Network Functions */
|
||||
case 0x5f: /* And Even More Network Functions */
|
||||
default:
|
||||
LOG(LOG_ERROR|LOG_MISC,"DOS:Unhandled call %02X al=%02X. Set al to default of 0",reg_ah,reg_al);
|
||||
reg_al=0x00; /* default value */
|
||||
break;
|
||||
};
|
||||
@ -847,16 +878,52 @@ static Bitu DOS_27Handler(void)
|
||||
if (DOS_ResizeMemory(dos.psp,¶)) DOS_Terminate(true);
|
||||
return CBRET_NONE;
|
||||
}
|
||||
static Bitu DOS_25Handler(void) {
|
||||
flags.type=t_UNKNOWN;
|
||||
if(Drives[reg_al]==0){
|
||||
reg_ax=0x8002;
|
||||
flags.cf=true;
|
||||
}else{
|
||||
flags.cf=false;
|
||||
reg_ax=0;
|
||||
if((reg_cx != 1) ||(reg_dx != 1))
|
||||
LOG(LOG_DOSMISC,"int 25 called but not as diskdetection");
|
||||
}
|
||||
return CBRET_NONE;
|
||||
}
|
||||
static Bitu DOS_26Handler(void) {
|
||||
LOG(LOG_DOSMISC,"int 26 called: hope for the best!");
|
||||
flags.type=t_UNKNOWN;
|
||||
if(Drives[reg_al]==0){
|
||||
|
||||
reg_ax=0x8002;
|
||||
flags.cf=true;
|
||||
}else{
|
||||
flags.cf=false;
|
||||
reg_ax=0;
|
||||
}
|
||||
return CBRET_NONE;
|
||||
}
|
||||
static Bitu DOS_28Handler(void) {
|
||||
return CBRET_NONE;
|
||||
}
|
||||
|
||||
static Bitu DOS_29Handler(void) {
|
||||
LOG_DEBUG("int 29 called");
|
||||
LOG(LOG_ERROR|LOG_MISC,"int 29 called");
|
||||
return CBRET_NONE;
|
||||
}
|
||||
|
||||
static Bitu DOS_CaseMapFunc(void) {
|
||||
//LOG(LOG_ERROR|LOG_MISC,"Case map routine called : %c",reg_al);
|
||||
return CBRET_NONE;
|
||||
};
|
||||
|
||||
void DOS_ShutDown(Section* sec)
|
||||
{
|
||||
for (Bit16u i=0;i<DOS_DRIVES;i++) delete Drives[i];
|
||||
};
|
||||
|
||||
|
||||
void DOS_Init(Section* sec) {
|
||||
MSG_Add("DOS_CONFIGFILE_HELP","Setting a memory size to 0 will disable it.\n");
|
||||
call_20=CALLBACK_Allocate();
|
||||
@ -867,6 +934,14 @@ void DOS_Init(Section* sec) {
|
||||
CALLBACK_Setup(call_21,DOS_21Handler,CB_IRET_STI);
|
||||
RealSetVec(0x21,CALLBACK_RealPointer(call_21));
|
||||
|
||||
call_25=CALLBACK_Allocate();
|
||||
CALLBACK_Setup(call_25,DOS_25Handler,CB_RETF);
|
||||
RealSetVec(0x25,CALLBACK_RealPointer(call_25));
|
||||
|
||||
call_26=CALLBACK_Allocate();
|
||||
CALLBACK_Setup(call_26,DOS_26Handler,CB_RETF);
|
||||
RealSetVec(0x26,CALLBACK_RealPointer(call_26));
|
||||
|
||||
call_27=CALLBACK_Allocate();
|
||||
CALLBACK_Setup(call_27,DOS_27Handler,CB_IRET);
|
||||
RealSetVec(0x27,CALLBACK_RealPointer(call_27));
|
||||
@ -889,6 +964,7 @@ void DOS_Init(Section* sec) {
|
||||
|
||||
dos.version.major=5;
|
||||
dos.version.minor=0;
|
||||
|
||||
/* Setup time and date */
|
||||
time_t curtime;struct tm *loctime;
|
||||
curtime = time (NULL);loctime = localtime (&curtime);
|
||||
@ -898,4 +974,12 @@ void DOS_Init(Section* sec) {
|
||||
dos.date.year=(Bit16u)loctime->tm_year+1900;
|
||||
Bit32u ticks=(Bit32u)((loctime->tm_hour*3600+loctime->tm_min*60+loctime->tm_sec)*18.2);
|
||||
mem_writed(BIOS_TIMER,ticks);
|
||||
|
||||
/* shutdown function */
|
||||
sec->AddDestroyFunction(&DOS_ShutDown);
|
||||
|
||||
/* case map routine INT 0x21 0x38 */
|
||||
call_casemap = CALLBACK_Allocate();
|
||||
CALLBACK_Setup(call_casemap,DOS_CaseMapFunc,CB_RETF);
|
||||
}
|
||||
|
||||
|
@ -145,6 +145,16 @@ Bit16u DOS_PSP::FindFreeFileEntry(void)
|
||||
return 0xff;
|
||||
};
|
||||
|
||||
Bit16u DOS_PSP::FindEntryByHandle(Bit8u handle)
|
||||
{
|
||||
PhysPt files=Real2Phys(sGet(sPSP,file_table));
|
||||
Bit16u max = sGet(sPSP,max_files);
|
||||
for (Bit16u i=0;i<sGet(sPSP,max_files);i++) {
|
||||
if (mem_readb(files+i)==handle) return i;
|
||||
}
|
||||
return 0xFF;
|
||||
};
|
||||
|
||||
void DOS_PSP::CopyFileTable(DOS_PSP* srcpsp)
|
||||
{
|
||||
/* Copy file table from calling process */
|
||||
@ -197,6 +207,23 @@ void DOS_PSP::SetFCB2(RealPt src)
|
||||
if (src) MEM_BlockCopy(PhysMake(seg,offsetof(sPSP,fcb2)),Real2Phys(src),16);
|
||||
};
|
||||
|
||||
bool DOS_PSP::SetNumFiles(Bit16u fileNum)
|
||||
{
|
||||
if (fileNum>20) {
|
||||
// Allocate needed paragraphs
|
||||
Bit16u para = (fileNum/16)+((fileNum%16)>0);
|
||||
RealPt data = RealMake(DOS_GetMemory(para),0);
|
||||
sSave(sPSP,file_table,data);
|
||||
sSave(sPSP,max_files,fileNum);
|
||||
Bit16u i;
|
||||
for (i=0; i<20; i++) SetFileHandle(i,sGet(sPSP,files[i]));
|
||||
for (i=20; i<fileNum; i++) SetFileHandle(i,0xFF);
|
||||
} else {
|
||||
sSave(sPSP,max_files,fileNum);
|
||||
};
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
void DOS_DTA::SetupSearch(Bit8u _sdrive,Bit8u _sattr,char * pattern) {
|
||||
sSave(sDTA,sdrive,_sdrive);
|
||||
@ -289,7 +316,8 @@ void DOS_FCB::SetSizeDateTime(Bit32u _size,Bit16u _date,Bit16u _time) {
|
||||
|
||||
void DOS_FCB::GetSizeDateTime(Bit32u & _size,Bit16u & _date,Bit16u & _time) {
|
||||
_size=sGet(sFCB,filesize);
|
||||
|
||||
_date=sGet(sFCB,date);
|
||||
_time=sGet(sFCB,time);
|
||||
}
|
||||
|
||||
void DOS_FCB::GetRecord(Bit16u & _cur_block,Bit8u & _cur_rec) {
|
||||
@ -349,15 +377,3 @@ void DOS_FCB::GetName(char * fillname) {
|
||||
fillname[14]=0;
|
||||
}
|
||||
|
||||
class DOS_MCB : public MemStruct{
|
||||
public:
|
||||
DOS_MCB(Bit16u seg) { SetPt(seg); }
|
||||
private:
|
||||
struct sMCB {
|
||||
Bit8u type;
|
||||
Bit16u psp_segment;
|
||||
Bit16u size;
|
||||
Bit8u unused[3];
|
||||
Bit8u filename[8];
|
||||
} GCC_ATTRIBUTE(packed);
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2002 The DOSBox Team
|
||||
* Copyright (C) 2002-2003 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -137,6 +137,9 @@ static bool MakeEnv(char * name,Bit16u * segment) {
|
||||
}
|
||||
|
||||
if (parentenv) {
|
||||
// hack to allow creation from envblock in unused mem (0xCD)
|
||||
if (readw(envread)==0xCDCD) writew(envread,0x0000);
|
||||
|
||||
for (envsize=0; ;envsize++) {
|
||||
if (envsize>=MAXENV - ENV_KEEPFREE) {
|
||||
DOS_SetError(DOSERR_ENVIRONMENT_INVALID);
|
||||
@ -173,20 +176,28 @@ bool DOS_NewPSP(Bit16u segment, Bit16u size)
|
||||
static void SetupPSP(Bit16u pspseg,Bit16u memsize,Bit16u envseg) {
|
||||
|
||||
/* Fix the PSP for psp and environment MCB's */
|
||||
MCB * pspmcb=(MCB *)HostMake(pspseg-1,0);
|
||||
pspmcb->psp_segment=pspseg;
|
||||
MCB * envmcb=(MCB *)HostMake(envseg-1,0);
|
||||
envmcb->psp_segment=pspseg;
|
||||
DOS_MCB mcb((Bit16u)(pspseg-1));
|
||||
mcb.SetPSPSeg(pspseg);
|
||||
mcb.SetPt((Bit16u)(envseg-1));
|
||||
mcb.SetPSPSeg(pspseg);
|
||||
|
||||
DOS_PSP psp(pspseg);
|
||||
psp.MakeNew(memsize);
|
||||
psp.SetEnvironment(envseg);
|
||||
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"));
|
||||
/* Copy file handles */
|
||||
if (DOS_PSP::rootpsp!=dos.psp) {
|
||||
// TODO: Improve this
|
||||
// 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 */
|
||||
psp.SetDTA(dos.dta);
|
||||
/* Setup the DTA */
|
||||
@ -229,8 +240,14 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) {
|
||||
if ((head.signature!=MAGIC1) && (head.signature!=MAGIC2)) iscom=true;
|
||||
else {
|
||||
headersize=head.headersize*16;
|
||||
imagesize=(head.pages)*512-headersize;
|
||||
if (head.extrabytes) imagesize-=(512-head.extrabytes);
|
||||
if (head.extrabytes) {
|
||||
imagesize = (head.pages-1)*512-headersize;
|
||||
imagesize += head.extrabytes % 512;
|
||||
} else
|
||||
imagesize = head.pages*512-headersize;
|
||||
|
||||
// always load st least 512 Bytes (dos cache/dos bug?)
|
||||
if (imagesize+headersize<512) imagesize = 512-headersize;
|
||||
}
|
||||
if (flags!=OVERLAY) {
|
||||
/* Create an environment block */
|
||||
@ -271,12 +288,12 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) {
|
||||
pos=headersize;DOS_SeekFile(fhandle,&pos,DOS_SEEK_SET);
|
||||
while (imagesize>0x7FFF) {
|
||||
readsize=0x8000;DOS_ReadFile(fhandle,loadaddress,&readsize);
|
||||
if (readsize!=0x8000) LOG_WARN("Illegal header");
|
||||
if (readsize!=0x8000) LOG(LOG_EXEC,"Illegal header");
|
||||
loadaddress+=0x8000;imagesize-=0x8000;
|
||||
}
|
||||
if (imagesize>0) {
|
||||
readsize=(Bit16u)imagesize;DOS_ReadFile(fhandle,loadaddress,&readsize);
|
||||
if (readsize!=imagesize) LOG_WARN("Illegal header");
|
||||
if (readsize!=imagesize) LOG(LOG_EXEC,"Illegal header");
|
||||
}
|
||||
/* Relocate the exe image */
|
||||
Bit16u relocate;
|
||||
@ -340,8 +357,8 @@ bool DOS_Execute(char * name,PhysPt block_pt,Bit8u flags) {
|
||||
mem_writew(SegPhys(ss)+reg_sp+2,RealSeg(csip));
|
||||
mem_writew(SegPhys(ss)+reg_sp+4,0x200);
|
||||
/* Setup the rest of the registers */
|
||||
reg_ax=0;
|
||||
reg_cx=reg_dx=reg_bx=reg_si=reg_di=reg_bp=0;
|
||||
reg_ax=0;reg_si=0x100;
|
||||
reg_cx=reg_dx=reg_bx=reg_di=reg_bp=0;
|
||||
SegSet16(ds,pspseg);SegSet16(es,pspseg);
|
||||
#if C_DEBUG
|
||||
/* Started from debug.com, then set breakpoint at start */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2002 The DOSBox Team
|
||||
* Copyright (C) 2002-2003 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -22,6 +22,7 @@
|
||||
#include <ctype.h>
|
||||
|
||||
#include "dosbox.h"
|
||||
#include "bios.h"
|
||||
#include "mem.h"
|
||||
#include "cpu.h"
|
||||
#include "dos_inc.h"
|
||||
@ -289,7 +290,7 @@ bool DOS_CloseFile(Bit16u entry) {
|
||||
//TODO Figure this out with devices :)
|
||||
|
||||
DOS_PSP psp(dos.psp);
|
||||
psp.SetFileHandle(entry,0xff);
|
||||
if (entry>STDPRN) psp.SetFileHandle(entry,0xff);
|
||||
|
||||
/* Devices won't allow themselves to be closed or killed */
|
||||
if (Files[handle]->Close()) {
|
||||
@ -332,7 +333,8 @@ bool DOS_CreateFile(char * name,Bit16u attributes,Bit16u * entry) {
|
||||
|
||||
bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry) {
|
||||
/* First check for devices */
|
||||
if (flags>2) LOG_DEBUG("Special file open command %X file %s",flags,name);
|
||||
if (flags>2) LOG(LOG_FILES|LOG_ERROR,"Special file open command %X file %s",flags,name);
|
||||
else LOG(LOG_FILES,"file open command %X file %s",flags,name);
|
||||
flags&=3;
|
||||
DOS_PSP psp(dos.psp);
|
||||
Bit8u handle=DOS_FindDevice((char *)name);
|
||||
@ -342,6 +344,7 @@ bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry) {
|
||||
} else {
|
||||
/* First check if the name is correct */
|
||||
if (!DOS_MakeName(name,fullname,&drive)) return false;
|
||||
|
||||
/* Check for a free file handle */
|
||||
for (i=0;i<DOS_FILES;i++) {
|
||||
if (!Files[i]) {
|
||||
@ -641,6 +644,27 @@ bool DOS_FCBOpen(Bit16u seg,Bit16u offset) {
|
||||
DOS_FCB fcb(seg,offset);
|
||||
char shortname[DOS_FCBNAME];Bit16u handle;
|
||||
fcb.GetName(shortname);
|
||||
|
||||
/* First check if the name is correct */
|
||||
Bit8u drive;
|
||||
char fullname[DOS_PATHLENGTH];
|
||||
if (!DOS_MakeName(shortname,fullname,&drive)) return false;
|
||||
|
||||
/* Check, if file is already opened */
|
||||
for (Bit16u i=0;i<DOS_FILES;i++) {
|
||||
DOS_PSP psp(dos.psp);
|
||||
if (Files[i] && Files[i]->IsOpen() && Files[i]->IsName(fullname)) {
|
||||
handle = psp.FindEntryByHandle(i);
|
||||
if (handle==0xFF) {
|
||||
// This shouldnt happen
|
||||
LOG(LOG_FILES|LOG_ERROR,"DOS: File %s is opened but has no psp entry.",shortname);
|
||||
return false;
|
||||
}
|
||||
fcb.FileOpen((Bit8u)handle);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!DOS_OpenFile(shortname,2,&handle)) return false;
|
||||
fcb.FileOpen((Bit8u)handle);
|
||||
return true;
|
||||
@ -712,7 +736,17 @@ Bit8u DOS_FCBWrite(Bit16u seg,Bit16u offset,Bit16u recno)
|
||||
Bit32u size;Bit16u date,time;
|
||||
fcb.GetSizeDateTime(size,date,time);
|
||||
if (pos+towrite>size) size=pos+towrite;
|
||||
//TODO Set time to current time?
|
||||
//time doesn't keep track of endofday
|
||||
date = DOS_PackDate(dos.date.year,dos.date.month,dos.date.day);
|
||||
Bit32u ticks = mem_readd(BIOS_TIMER);
|
||||
Bit32u seconds = (ticks*10)/182;
|
||||
Bit16u hour = (Bit16u)(seconds/3600);
|
||||
Bit16u min = (Bit16u)((seconds % 3600)/60);
|
||||
Bit16u sec = (Bit16u)(seconds % 60);
|
||||
time = DOS_PackTime(hour,min,sec);
|
||||
Bit8u temp=RealHandle(fhandle);
|
||||
Files[temp]->time=time;
|
||||
Files[temp]->date=date;
|
||||
fcb.SetSizeDateTime(size,date,time);
|
||||
if (++cur_rec>127) { cur_block++;cur_rec=0; }
|
||||
fcb.SetRecord(cur_block,cur_rec);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2002 The DOSBox Team
|
||||
* Copyright (C) 2002-2003 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -45,7 +45,7 @@ bool DOS_IOCTL(void) {
|
||||
reg_dx=Files[handle]->GetInformation();
|
||||
return true;
|
||||
case 0x07: /* Get Output Status */
|
||||
LOG_DEBUG("DOS:IOCTL:07:Fakes output status is ready for handle %d",handle);
|
||||
LOG(LOG_IOCTL,"DOS:IOCTL:07:Fakes output status is ready for handle %d",handle);
|
||||
reg_al=0xff;
|
||||
return true;
|
||||
case 0x08: /* Check if block device removable */
|
||||
@ -71,7 +71,7 @@ bool DOS_IOCTL(void) {
|
||||
mem_writeb(ptr+6,0x00); // media type (00=other type)
|
||||
break;
|
||||
default :
|
||||
LOG_ERROR("DOS:IOCTL Call 0D:%2X Drive %2X unhandled",reg_cl,drive);
|
||||
LOG(LOG_IOCTL|LOG_ERROR,"DOS:IOCTL Call 0D:%2X Drive %2X unhandled",reg_cl,drive);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@ -94,7 +94,7 @@ bool DOS_IOCTL(void) {
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LOG_ERROR("DOS:IOCTL Call %2X unhandled",reg_al);
|
||||
LOG(LOG_DOSMISC|LOG_ERROR,"DOS:IOCTL Call %2X unhandled",reg_al);
|
||||
return false;
|
||||
};
|
||||
return false;
|
||||
|
@ -27,33 +27,32 @@
|
||||
static Bit16u memAllocStrategy = 0x00;
|
||||
|
||||
static void DOS_CompressMemory(void) {
|
||||
MCB * pmcb;MCB * pmcbnext;
|
||||
Bit16u mcb_segment;
|
||||
mcb_segment=dos.firstMCB;
|
||||
pmcb=(MCB *)HostMake(mcb_segment,0);
|
||||
while (pmcb->type!=0x5a) {
|
||||
pmcbnext=pmcbnext=(MCB *)HostMake(mcb_segment+pmcb->size+1,0);
|
||||
if ((pmcb->psp_segment==0) && (pmcbnext->psp_segment==0)) {
|
||||
pmcb->size+=pmcbnext->size+1;
|
||||
pmcb->type=pmcbnext->type;
|
||||
Bit16u mcb_segment=dos.firstMCB;
|
||||
DOS_MCB mcb(mcb_segment);
|
||||
DOS_MCB mcb_next(0);
|
||||
|
||||
while (mcb.GetType()!=0x5a) {
|
||||
mcb_next.SetPt((Bit16u)(mcb_segment+mcb.GetSize()+1));
|
||||
if ((mcb.GetPSPSeg()==0) && (mcb_next.GetPSPSeg()==0)) {
|
||||
mcb.SetSize(mcb.GetSize()+mcb_next.GetSize()+1);
|
||||
mcb.SetType(mcb_next.GetType());
|
||||
} else {
|
||||
mcb_segment+=pmcb->size+1;
|
||||
pmcb=(MCB *)HostMake(mcb_segment,0);
|
||||
mcb_segment+=mcb.GetSize()+1;
|
||||
mcb.SetPt(mcb_segment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DOS_FreeProcessMemory(Bit16u pspseg) {
|
||||
MCB * pmcb;
|
||||
Bit16u mcb_segment=dos.firstMCB;
|
||||
pmcb=(MCB *)HostMake(mcb_segment,0);
|
||||
DOS_MCB mcb(mcb_segment);
|
||||
while (true) {
|
||||
if (pmcb->psp_segment==pspseg) {
|
||||
pmcb->psp_segment=MCB_FREE;
|
||||
if (mcb.GetPSPSeg()==pspseg) {
|
||||
mcb.SetPSPSeg(MCB_FREE);
|
||||
}
|
||||
mcb_segment+=pmcb->size+1;
|
||||
if (pmcb->type==0x5a) break;
|
||||
pmcb=(MCB *)HostMake(mcb_segment,0);
|
||||
if (mcb.GetType()==0x5a) break;
|
||||
mcb_segment+=mcb.GetSize()+1;
|
||||
mcb.SetPt(mcb_segment);
|
||||
}
|
||||
DOS_CompressMemory();
|
||||
};
|
||||
@ -69,60 +68,61 @@ void DOS_SetMemAllocStrategy(Bit16u strat)
|
||||
};
|
||||
|
||||
bool DOS_AllocateMemory(Bit16u * segment,Bit16u * blocks) {
|
||||
MCB * pmcb;MCB * pmcbnext;
|
||||
Bit16u bigsize=0;Bit16u mcb_segment;
|
||||
bool stop=false;mcb_segment=dos.firstMCB;
|
||||
DOS_CompressMemory();
|
||||
Bit16u bigsize=0;Bit16u mcb_segment=dos.firstMCB;
|
||||
DOS_MCB mcb(0);
|
||||
DOS_MCB mcb_next(0);
|
||||
bool stop=false;
|
||||
while(!stop) {
|
||||
pmcb=(MCB *)HostMake(mcb_segment,0);
|
||||
if (pmcb->psp_segment==0) {
|
||||
mcb.SetPt(mcb_segment);
|
||||
if (mcb.GetPSPSeg()==0) {
|
||||
/* Check for enough free memory in current block */
|
||||
if (pmcb->size<(*blocks)) {
|
||||
if (bigsize<pmcb->size) {
|
||||
bigsize=pmcb->size;
|
||||
Bit16u block_size=mcb.GetSize();
|
||||
if (block_size<(*blocks)) {
|
||||
if (bigsize<block_size) {
|
||||
bigsize=block_size;
|
||||
}
|
||||
|
||||
} else if (pmcb->size==*blocks) {
|
||||
pmcb->psp_segment=dos.psp;
|
||||
} else if (block_size==*blocks) {
|
||||
mcb.SetPSPSeg(dos.psp);
|
||||
*segment=mcb_segment+1;
|
||||
return true;
|
||||
} else {
|
||||
// TODO: Strategy "1": Best matching block
|
||||
/* If so allocate it */
|
||||
if ((memAllocStrategy & 0x03)==0) {
|
||||
pmcbnext=(MCB *)HostMake(mcb_segment+*blocks+1,0);
|
||||
pmcbnext->psp_segment=MCB_FREE;
|
||||
pmcbnext->type=pmcb->type;
|
||||
pmcbnext->size=pmcb->size-*blocks-1;
|
||||
pmcb->size=*blocks;
|
||||
pmcb->type=0x4D;
|
||||
pmcb->psp_segment=dos.psp;
|
||||
if ((memAllocStrategy & 0x03)==0) {
|
||||
mcb_next.SetPt((Bit16u)(mcb_segment+*blocks+1));
|
||||
mcb_next.SetPSPSeg(MCB_FREE);
|
||||
mcb_next.SetType(mcb.GetType());
|
||||
mcb_next.SetSize(block_size-*blocks-1);
|
||||
mcb.SetSize(*blocks);
|
||||
mcb.SetType(0x4d);
|
||||
mcb.SetPSPSeg(dos.psp);
|
||||
//TODO Filename
|
||||
*segment=mcb_segment+1;
|
||||
return true;
|
||||
} else {
|
||||
// * Last Block *
|
||||
// New created block
|
||||
*segment = mcb_segment+1+pmcb->size-*blocks;
|
||||
pmcbnext=(MCB *)HostMake(*segment-1,0);
|
||||
pmcbnext->size = *blocks;
|
||||
pmcbnext->type = pmcb->type;
|
||||
pmcbnext->psp_segment = dos.psp;
|
||||
*segment = mcb_segment+1+block_size - *blocks;
|
||||
mcb_next.SetPt((Bit16u)(*segment-1));
|
||||
mcb_next.SetSize(*blocks);
|
||||
mcb_next.SetType(mcb.GetType());
|
||||
mcb_next.SetPSPSeg(dos.psp);
|
||||
// Old Block
|
||||
pmcb->size = pmcb->size-*blocks-1;
|
||||
pmcb->psp_segment = MCB_FREE;
|
||||
pmcb->type = 0x4D;
|
||||
mcb.SetSize(block_size-*blocks-1);
|
||||
mcb.SetPSPSeg(MCB_FREE);
|
||||
mcb.SetType(0x4D);
|
||||
return true;
|
||||
};
|
||||
}
|
||||
}
|
||||
/* Onward to the next MCB if there is one */
|
||||
if (pmcb->type==0x5a) {
|
||||
if (mcb.GetType()==0x5a) {
|
||||
*blocks=bigsize;
|
||||
DOS_SetError(DOSERR_INSUFFICIENT_MEMORY);
|
||||
return false;
|
||||
}
|
||||
mcb_segment+=pmcb->size+1;
|
||||
mcb_segment+=mcb.GetSize()+1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -130,32 +130,31 @@ bool DOS_AllocateMemory(Bit16u * segment,Bit16u * blocks) {
|
||||
|
||||
bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks) {
|
||||
DOS_CompressMemory();
|
||||
MCB * pmcb,* pmcbnext,* pmcbnew;
|
||||
pmcb=(MCB *)HostMake(segment-1,0);
|
||||
pmcbnext=(MCB *)HostMake(segment+pmcb->size,0);
|
||||
Bit16u total=pmcb->size;
|
||||
if (pmcb->type!=0x5a) {
|
||||
if (pmcbnext->psp_segment==MCB_FREE) {
|
||||
total+=pmcbnext->size+1;
|
||||
DOS_MCB mcb(segment-1);
|
||||
Bit16u total=mcb.GetSize();
|
||||
DOS_MCB mcb_next(segment+total);
|
||||
if (mcb.GetType()!=0x5a) {
|
||||
if (mcb_next.GetPSPSeg()==MCB_FREE) {
|
||||
total+=mcb_next.GetSize()+1;
|
||||
}
|
||||
};
|
||||
}
|
||||
if (*blocks<total) {
|
||||
if (pmcb->type!=0x5a) {
|
||||
pmcb->type=pmcbnext->type;
|
||||
if (mcb.GetType()!=0x5a) {
|
||||
mcb.SetType(mcb_next.GetType());
|
||||
}
|
||||
pmcb->size=*blocks;
|
||||
pmcbnew=(MCB *)HostMake(segment+*blocks,0);
|
||||
pmcbnew->size=total-*blocks-1;
|
||||
pmcbnew->type=pmcb->type;
|
||||
pmcbnew->psp_segment=MCB_FREE;
|
||||
pmcb->type=0x4D;
|
||||
mcb.SetSize(*blocks);
|
||||
mcb_next.SetPt((Bit16u)(segment+*blocks));
|
||||
mcb_next.SetSize(total-*blocks-1);
|
||||
mcb_next.SetType(mcb.GetType());
|
||||
mcb_next.SetPSPSeg(MCB_FREE);
|
||||
mcb.SetType(0x4d);
|
||||
return true;
|
||||
}
|
||||
if (*blocks==total) {
|
||||
if (pmcb->type!=0x5a) {
|
||||
pmcb->type=pmcbnext->type;
|
||||
if (mcb.GetType()!=0x5a) {
|
||||
mcb.SetType(mcb_next.GetType());
|
||||
}
|
||||
pmcb->size=*blocks;
|
||||
mcb.SetSize(*blocks);
|
||||
return true;
|
||||
}
|
||||
*blocks=total;
|
||||
@ -166,9 +165,8 @@ bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks) {
|
||||
|
||||
bool DOS_FreeMemory(Bit16u segment) {
|
||||
//TODO Check if allowed to free this segment
|
||||
MCB * pmcb;
|
||||
pmcb=(MCB *)HostMake(segment-1,0);
|
||||
pmcb->psp_segment=MCB_FREE;
|
||||
DOS_MCB mcb(segment-1);
|
||||
mcb.SetPSPSeg(MCB_FREE);
|
||||
DOS_CompressMemory();
|
||||
return true;
|
||||
}
|
||||
@ -177,10 +175,10 @@ bool DOS_FreeMemory(Bit16u segment) {
|
||||
|
||||
|
||||
void DOS_SetupMemory(void) {
|
||||
MCB * mcb=(MCB *) HostMake(MEM_START,0);
|
||||
mcb->psp_segment=MCB_FREE; //Free
|
||||
mcb->size=0x9FFE - MEM_START;
|
||||
mcb->type=0x5a; //Last Block
|
||||
DOS_MCB mcb((Bit16u)MEM_START);
|
||||
mcb.SetPSPSeg(MCB_FREE); //Free
|
||||
mcb.SetSize(0x9FFE - MEM_START);
|
||||
mcb.SetType(0x5a); //Last Block
|
||||
dos.firstMCB=MEM_START;
|
||||
dos_infoblock.SetFirstMCB(MEM_START);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2002 The DOSBox Team
|
||||
* Copyright (C) 2002-2003 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -44,7 +44,7 @@ static Bitu INT2F_Handler(void) {
|
||||
if ((*loop_multiplex->handler)()) return CBRET_NONE;
|
||||
loop_multiplex=loop_multiplex->next;
|
||||
}
|
||||
LOG_WARN("DOS:Multiplex Unhandled call %4X",reg_ax);
|
||||
LOG(LOG_ERROR,"DOS:Multiplex Unhandled call %4X",reg_ax);
|
||||
return CBRET_NONE;
|
||||
};
|
||||
|
||||
|
844
src/dos/dos_mscdex.cpp
Normal file
844
src/dos/dos_mscdex.cpp
Normal file
@ -0,0 +1,844 @@
|
||||
/*
|
||||
* Copyright (C) 2002-2003 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "cpu.h"
|
||||
#include "callback.h"
|
||||
#include "dos_system.h"
|
||||
#include "dos_inc.h"
|
||||
#include "setup.h"
|
||||
|
||||
#include "cdrom.h"
|
||||
|
||||
#define MSCDEX_VERSION_HIGH 2
|
||||
#define MSCDEX_VERSION_LOW 23
|
||||
#define MSCDEX_MAX_DRIVES 5
|
||||
|
||||
// Error Codes
|
||||
#define MSCDEX_ERROR_UNKNOWN_DRIVE 15
|
||||
#define MSCDEX_ERROR_DRIVE_NOT_READY 21
|
||||
|
||||
// Request Status
|
||||
#define REQUEST_STATUS_DONE 0x0100
|
||||
#define REQUEST_STATUS_ERROR 0x8000
|
||||
|
||||
// Use cdrom Interface
|
||||
int useCdromInterface = CDROM_USE_SDL;
|
||||
int forceCD = -1;
|
||||
|
||||
static Bitu MSCDEX_Strategy_Handler(void);
|
||||
static Bitu MSCDEX_Interrupt_Handler(void);
|
||||
|
||||
class DOS_DeviceHeader:public MemStruct
|
||||
{
|
||||
public:
|
||||
DOS_DeviceHeader(PhysPt ptr) { pt = ptr; };
|
||||
|
||||
void SetNextDeviceHeader (RealPt ptr) { sSave(sDeviceHeader,nextDeviceHeader,ptr); };
|
||||
RealPt GetNextDeviceHeader (void) { return sGet(sDeviceHeader,nextDeviceHeader); };
|
||||
void SetAttribute (Bit16u atr) { sSave(sDeviceHeader,devAttributes,atr); };
|
||||
void SetDriveLetter (Bit8u letter) { sSave(sDeviceHeader,driveLetter,letter); };
|
||||
void SetNumSubUnits (Bit8u num) { sSave(sDeviceHeader,numSubUnits,num); };
|
||||
Bit8u GetNumSubUnits (void) { return sGet(sDeviceHeader,numSubUnits); };
|
||||
void SetName (char* _name) { MEM_BlockWrite(pt+offsetof(sDeviceHeader,name),_name,8); };
|
||||
void SetInterrupt (Bit16u ofs) { sSave(sDeviceHeader,interrupt,ofs); };
|
||||
void SetStrategy (Bit16u ofs) { sSave(sDeviceHeader,strategy,ofs); };
|
||||
|
||||
public:
|
||||
#pragma pack(1)
|
||||
struct sDeviceHeader{
|
||||
RealPt nextDeviceHeader;
|
||||
Bit16u devAttributes;
|
||||
Bit16u strategy;
|
||||
Bit16u interrupt;
|
||||
Bit8u name[8];
|
||||
Bit16u wReserved;
|
||||
Bit8u driveLetter;
|
||||
Bit8u numSubUnits;
|
||||
} TDeviceHeader;
|
||||
#pragma pack()
|
||||
};
|
||||
|
||||
class CMscdex
|
||||
{
|
||||
public:
|
||||
CMscdex (void);
|
||||
~CMscdex (void);
|
||||
|
||||
Bit16u GetVersion (void) { return (MSCDEX_VERSION_HIGH<<8)+MSCDEX_VERSION_LOW; };
|
||||
Bit16u GetNumDrives (void) { return numDrives; };
|
||||
Bit16u GetFirstDrive (void) { return dinfo[0].drive; };
|
||||
Bit8u GetSubUnit (Bit16u _drive);
|
||||
bool GetUPC (Bit8u subUnit, Bit8u& attr, char* upc);
|
||||
|
||||
bool PlayAudioSector (Bit8u subUnit, Bit32u start, Bit32u length);
|
||||
bool PlayAudioMSF (Bit8u subUnit, Bit32u start, Bit32u length);
|
||||
bool StopAudio (Bit8u subUnit);
|
||||
bool GetAudioStatus (Bit8u subUnit, bool& playing, bool& pause, TMSF& start, TMSF& end);
|
||||
|
||||
bool GetSubChannelData (Bit8u subUnit, Bit8u& attr, Bit8u& track, Bit8u &index, TMSF& rel, TMSF& abs);
|
||||
|
||||
int AddDrive (Bit16u _drive, char* physicalPath, Bit8u& subUnit);
|
||||
void GetDrives (PhysPt data);
|
||||
void GetDriverInfo (PhysPt data);
|
||||
bool GetCopyrightName (Bit16u drive, PhysPt data) { return false; };
|
||||
bool GetAbstractName (Bit16u drive, PhysPt data) { return false; };
|
||||
bool GetDocumentationName(Bit16u drive, PhysPt data) { return false; };
|
||||
bool ReadVTOC (Bit16u drive, Bit16u volume, PhysPt data, Bit16u& error) { return false; };
|
||||
bool ReadSectors (Bit16u drive, Bit32u sector, Bit16u num, PhysPt data);
|
||||
bool ReadSectors (Bit8u subUnit, bool raw, Bit32u sector, Bit16u num, PhysPt data);
|
||||
bool ReadSectorsMSF (Bit8u subUnit, bool raw, Bit32u sector, Bit16u num, PhysPt data);
|
||||
bool SendDriverRequest (Bit16u drive, PhysPt data);
|
||||
bool IsValidDrive (Bit16u drive);
|
||||
bool GetCDInfo (Bit8u subUnit, Bit8u& tr1, Bit8u& tr2, TMSF& leadOut);
|
||||
Bit32u GetVolumeSize (Bit8u subUnit);
|
||||
bool GetTrackInfo (Bit8u subUnit, Bit8u track, Bit8u& attr, TMSF& start);
|
||||
Bit16u GetStatusWord (Bit8u subUnit);
|
||||
bool GetCurrentPos (Bit8u subUnit, TMSF& pos);
|
||||
Bit32u GetDeviceStatus (Bit8u subUnit);
|
||||
bool GetMediaStatus (Bit8u subUnit, Bit8u& status);
|
||||
bool LoadUnloadMedia (Bit8u subUnit, bool unload);
|
||||
bool ResumeAudio (Bit8u subUnit);
|
||||
bool GetMediaStatus (Bit8u subUnit, bool& media, bool& changed, bool& trayOpen);
|
||||
|
||||
private:
|
||||
|
||||
Bit16u numDrives;
|
||||
|
||||
typedef struct SDriveInfo {
|
||||
Bit8u drive; // drive letter in dosbox
|
||||
Bit8u physDrive; // drive letter in system
|
||||
bool audioPlay; // audio playing active
|
||||
bool audioPaused; // audio playing paused
|
||||
Bit32u audioStart; // StartLoc for resume
|
||||
Bit32u audioEnd; // EndLoc for resume
|
||||
bool locked; // drive locked ?
|
||||
bool lastResult; // last operation success ?
|
||||
Bit32u volumeSize; // for media change
|
||||
} TDriveInfo;
|
||||
|
||||
TDriveInfo dinfo[MSCDEX_MAX_DRIVES];
|
||||
CDROM_Interface* cdrom[MSCDEX_MAX_DRIVES];
|
||||
|
||||
public:
|
||||
Bit16u rootDriverHeaderSeg;
|
||||
};
|
||||
|
||||
CMscdex::CMscdex(void)
|
||||
{
|
||||
numDrives = 0;
|
||||
rootDriverHeaderSeg = 0;
|
||||
|
||||
memset(dinfo,0,sizeof(dinfo));
|
||||
for (Bit32u i=0; i<MSCDEX_MAX_DRIVES; i++) cdrom[i] = 0;
|
||||
};
|
||||
|
||||
CMscdex::~CMscdex(void)
|
||||
{
|
||||
for (Bit16u i=0; i<GetNumDrives(); i++) {
|
||||
delete (cdrom)[i];
|
||||
cdrom[i] = 0;
|
||||
};
|
||||
};
|
||||
|
||||
void CMscdex::GetDrives(PhysPt data)
|
||||
{
|
||||
for (Bit16u i=0; i<GetNumDrives(); i++) mem_writeb(data+i,dinfo[i].drive);
|
||||
};
|
||||
|
||||
bool CMscdex::IsValidDrive(Bit16u _drive)
|
||||
{
|
||||
for (Bit16u i=0; i<GetNumDrives(); i++) if (dinfo[i].drive==_drive) return true;
|
||||
return false;
|
||||
};
|
||||
|
||||
Bit8u CMscdex::GetSubUnit(Bit16u _drive)
|
||||
{
|
||||
for (Bit16u i=0; i<GetNumDrives(); i++) if (dinfo[i].drive==_drive) return (Bit8u)i;
|
||||
return 0xff;
|
||||
};
|
||||
|
||||
int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit)
|
||||
{
|
||||
subUnit = 0;
|
||||
if (GetNumDrives()==0) {
|
||||
|
||||
Bit16u driverSize = sizeof(DOS_DeviceHeader::sDeviceHeader) + 10; // 10 = Bytes for 3 callbacks
|
||||
|
||||
// Create Device Header
|
||||
Bit16u seg = DOS_GetMemory(driverSize/16+((driverSize%16)>0));
|
||||
DOS_DeviceHeader devHeader(PhysMake(seg,0));
|
||||
devHeader.SetNextDeviceHeader (0xFFFFFFFF);
|
||||
devHeader.SetDriveLetter ('A'+_drive);
|
||||
devHeader.SetNumSubUnits (1);
|
||||
devHeader.SetName ("MSCD001 ");
|
||||
|
||||
// Create Callback Strategy
|
||||
Bit16u off = sizeof(DOS_DeviceHeader::sDeviceHeader);
|
||||
Bitu call_strategy=CALLBACK_Allocate();
|
||||
CallBack_Handlers[call_strategy]=MSCDEX_Strategy_Handler;
|
||||
real_writeb(seg,off+0,(Bit8u)0xFE); //GRP 4
|
||||
real_writeb(seg,off+1,(Bit8u)0x38); //Extra Callback instruction
|
||||
real_writew(seg,off+2,call_strategy); //The immediate word
|
||||
real_writeb(seg,off+4,(Bit8u)0xCB); //A RETF Instruction
|
||||
devHeader.SetStrategy(off);
|
||||
|
||||
// Create Callback Interrupt
|
||||
off += 5;
|
||||
Bitu call_interrupt=CALLBACK_Allocate();
|
||||
CallBack_Handlers[call_interrupt]=MSCDEX_Interrupt_Handler;
|
||||
real_writeb(seg,off+0,(Bit8u)0xFE); //GRP 4
|
||||
real_writeb(seg,off+1,(Bit8u)0x38); //Extra Callback instruction
|
||||
real_writew(seg,off+2,call_interrupt); //The immediate word
|
||||
real_writeb(seg,off+4,(Bit8u)0xCB); //A RETF Instruction
|
||||
devHeader.SetInterrupt(off);
|
||||
|
||||
rootDriverHeaderSeg = seg;
|
||||
|
||||
} else {
|
||||
// Error check, driveletter have to be in a row
|
||||
if (dinfo[numDrives-1].drive+1!=_drive) return 1;
|
||||
};
|
||||
|
||||
if (GetNumDrives()+1<MSCDEX_MAX_DRIVES) {
|
||||
// Set return type to ok
|
||||
int result = 0;
|
||||
// Get Mounttype and init needed cdrom interface
|
||||
switch (CDROM_GetMountType(physicalPath,forceCD)) {
|
||||
case 0x00 : {
|
||||
LOG(LOG_MISC,"MSCDEX: Mounting physical cdrom: %s" ,physicalPath);
|
||||
#if defined (WIN32)
|
||||
// Check OS
|
||||
OSVERSIONINFO osi;
|
||||
osi.dwOSVersionInfoSize = sizeof(osi);
|
||||
GetVersionEx(&osi);
|
||||
if ((osi.dwPlatformId==VER_PLATFORM_WIN32_NT) && (osi.dwMajorVersion>4)) {
|
||||
// WIN NT/200/XP
|
||||
if (useCdromInterface==CDROM_USE_ASPI) {
|
||||
cdrom[numDrives] = new CDROM_Interface_Aspi();
|
||||
LOG(LOG_MISC,"MSCDEX: ASPI Interface.");
|
||||
break;
|
||||
} else if (useCdromInterface==CDROM_USE_IOCTL) {
|
||||
cdrom[numDrives] = new CDROM_Interface_Ioctl();
|
||||
LOG(LOG_MISC,"MSCDEX: IOCTL Interface.");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Win 95/98/ME - always use ASPI
|
||||
cdrom[numDrives] = new CDROM_Interface_Aspi();
|
||||
LOG(LOG_MISC,"MSCDEX: ASPI Interface.");
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
cdrom[numDrives] = new CDROM_Interface_SDL();
|
||||
LOG(LOG_MISC,"MSCDEX: SDL Interface.");
|
||||
} break;
|
||||
case 0x01 : // iso cdrom interface
|
||||
// FIXME: Not yet supported
|
||||
LOG(LOG_MISC|LOG_ERROR,"MSCDEX: Mounting iso file as cdrom: %s" ,physicalPath);
|
||||
cdrom[numDrives] = new CDROM_Interface_Fake;
|
||||
return 2;
|
||||
break;
|
||||
case 0x02 : // fake cdrom interface (directories)
|
||||
cdrom[numDrives] = new CDROM_Interface_Fake;
|
||||
LOG(LOG_MISC,"MSCDEX: Mounting directory as cdrom: %s",physicalPath);
|
||||
LOG(LOG_MISC,"MSCDEX: You wont have full MSCDEX support !");
|
||||
result = 5;
|
||||
break;
|
||||
default : // weird result
|
||||
return 6;
|
||||
};
|
||||
if (!cdrom[numDrives]->SetDevice(physicalPath,forceCD)) return 3;
|
||||
subUnit = numDrives;
|
||||
// Set drive
|
||||
DOS_DeviceHeader devHeader(PhysMake(rootDriverHeaderSeg,0));
|
||||
devHeader.SetNumSubUnits(devHeader.GetNumSubUnits()+1);
|
||||
dinfo[numDrives].drive = (Bit8u)_drive;
|
||||
dinfo[numDrives].physDrive = toupper(physicalPath[0]);
|
||||
numDrives++;
|
||||
return result;
|
||||
}
|
||||
return 4;
|
||||
};
|
||||
|
||||
void CMscdex::GetDriverInfo (PhysPt data)
|
||||
{
|
||||
for (Bit16u i=0; i<GetNumDrives(); i++) {
|
||||
mem_writeb(data ,0x00);
|
||||
mem_writed(data+1,RealMake(rootDriverHeaderSeg,0));
|
||||
data+=5;
|
||||
};
|
||||
};
|
||||
|
||||
bool CMscdex::GetCDInfo(Bit8u subUnit, Bit8u& tr1, Bit8u& tr2, TMSF& leadOut)
|
||||
{
|
||||
int tr1i,tr2i;
|
||||
dinfo[subUnit].lastResult = cdrom[subUnit]->GetAudioTracks(tr1i,tr2i,leadOut);
|
||||
if (!dinfo[subUnit].lastResult) {
|
||||
tr1 = tr2 = 0;
|
||||
memset(&leadOut,0,sizeof(leadOut));
|
||||
} else {
|
||||
tr1 = (Bit8u) tr1i;
|
||||
tr2 = (Bit8u) tr2i;
|
||||
}
|
||||
return dinfo[subUnit].lastResult;
|
||||
}
|
||||
|
||||
bool CMscdex::GetTrackInfo(Bit8u subUnit, Bit8u track, Bit8u& attr, TMSF& start)
|
||||
{
|
||||
dinfo[subUnit].lastResult = cdrom[subUnit]->GetAudioTrackInfo(track,start,attr);
|
||||
if (!dinfo[subUnit].lastResult) {
|
||||
attr = 0;
|
||||
memset(&start,0,sizeof(start));
|
||||
};
|
||||
return dinfo[subUnit].lastResult;
|
||||
};
|
||||
|
||||
bool CMscdex::PlayAudioSector(Bit8u subUnit, Bit32u sector, Bit32u length)
|
||||
{
|
||||
// If value from last stop is used, this is meant as a resume
|
||||
// better start using resume command
|
||||
if (dinfo[subUnit].audioPaused && (sector==dinfo[subUnit].audioStart)) {
|
||||
dinfo[subUnit].lastResult = cdrom[subUnit]->PauseAudio(true);
|
||||
} else
|
||||
dinfo[subUnit].lastResult = cdrom[subUnit]->PlayAudioSector(sector,length);
|
||||
|
||||
if (dinfo[subUnit].lastResult) {
|
||||
dinfo[subUnit].audioPlay = true;
|
||||
dinfo[subUnit].audioPaused = false;
|
||||
dinfo[subUnit].audioStart = sector;
|
||||
dinfo[subUnit].audioEnd = length;
|
||||
};
|
||||
return dinfo[subUnit].lastResult;
|
||||
};
|
||||
|
||||
bool CMscdex::PlayAudioMSF(Bit8u subUnit, Bit32u start, Bit32u length)
|
||||
{
|
||||
Bit8u min = (start>>16) & 0xFF;
|
||||
Bit8u sec = (start>> 8) & 0xFF;
|
||||
Bit8u fr = (start>> 0) & 0xFF;
|
||||
Bit32u sector = min*60*76+sec*75+fr - 150;
|
||||
min = (length>>16) & 0xFF;
|
||||
sec = (length>> 8) & 0xFF;
|
||||
fr = (length>> 0) & 0xFF;
|
||||
Bit32u seclen = min*60*76+sec*75+fr - 150;
|
||||
return dinfo[subUnit].lastResult = PlayAudioSector(subUnit,sector,seclen);
|
||||
};
|
||||
|
||||
bool CMscdex::GetSubChannelData(Bit8u subUnit, Bit8u& attr, Bit8u& track, Bit8u &index, TMSF& rel, TMSF& abs)
|
||||
{
|
||||
dinfo[subUnit].lastResult = cdrom[subUnit]->GetAudioSub(attr,track,index,rel,abs);
|
||||
if (!dinfo[subUnit].lastResult) {
|
||||
attr = track = index = 0;
|
||||
memset(&rel,0,sizeof(rel));
|
||||
memset(&abs,0,sizeof(abs));
|
||||
};
|
||||
return dinfo[subUnit].lastResult;
|
||||
};
|
||||
|
||||
bool CMscdex::GetAudioStatus(Bit8u subUnit, bool& playing, bool& pause, TMSF& start, TMSF& end)
|
||||
{
|
||||
dinfo[subUnit].lastResult = cdrom[subUnit]->GetAudioStatus(playing,pause);
|
||||
if (dinfo[subUnit].lastResult) {
|
||||
// Start
|
||||
Bit32u addr = dinfo[subUnit].audioStart + 150;
|
||||
start.fr = (Bit8u)(addr%75); addr/=75;
|
||||
start.sec = (Bit8u)(addr%60);
|
||||
start.min = (Bit8u)(addr/60);
|
||||
// End
|
||||
addr = dinfo[subUnit].audioEnd + 150;
|
||||
end.fr = (Bit8u)(addr%75); addr/=75;
|
||||
end.sec = (Bit8u)(addr%60);
|
||||
end.min = (Bit8u)(addr/60);
|
||||
} else {
|
||||
playing = false;
|
||||
pause = false;
|
||||
memset(&start,0,sizeof(start));
|
||||
memset(&end,0,sizeof(end));
|
||||
};
|
||||
|
||||
return dinfo[subUnit].lastResult;
|
||||
};
|
||||
|
||||
bool CMscdex::StopAudio(Bit8u subUnit)
|
||||
{
|
||||
if (dinfo[subUnit].audioPlay) dinfo[subUnit].lastResult = cdrom[subUnit]->PauseAudio(false);
|
||||
else dinfo[subUnit].lastResult = cdrom[subUnit]->StopAudio();
|
||||
|
||||
if (dinfo[subUnit].lastResult) {
|
||||
if (dinfo[subUnit].audioPlay) {
|
||||
TMSF pos;
|
||||
GetCurrentPos(subUnit,pos);
|
||||
dinfo[subUnit].audioStart = pos.min*60*76+pos.sec*75+pos.fr - 150;
|
||||
dinfo[subUnit].audioPaused = true;
|
||||
} else {
|
||||
dinfo[subUnit].audioPaused = false;
|
||||
dinfo[subUnit].audioStart = 0;
|
||||
dinfo[subUnit].audioEnd = 0;
|
||||
};
|
||||
dinfo[subUnit].audioPlay = false;
|
||||
};
|
||||
return dinfo[subUnit].lastResult;
|
||||
};
|
||||
|
||||
bool CMscdex::ResumeAudio(Bit8u subUnit)
|
||||
{
|
||||
return dinfo[subUnit].lastResult = PlayAudioSector(subUnit,dinfo[subUnit].audioStart,dinfo[subUnit].audioEnd);
|
||||
};
|
||||
|
||||
Bit32u CMscdex::GetVolumeSize(Bit8u subUnit)
|
||||
{
|
||||
Bit8u tr1,tr2;
|
||||
TMSF leadOut;
|
||||
dinfo[subUnit].lastResult = GetCDInfo(subUnit,tr1,tr2,leadOut);
|
||||
if (dinfo[subUnit].lastResult) return (leadOut.min*60*75)+(leadOut.sec*75)+leadOut.fr;
|
||||
return 0;
|
||||
};
|
||||
|
||||
bool CMscdex::GetUPC(Bit8u subUnit, Bit8u& attr, char* upc)
|
||||
{
|
||||
return dinfo[subUnit].lastResult = cdrom[subUnit]->GetUPC(attr,&upc[0]);
|
||||
};
|
||||
|
||||
bool CMscdex::ReadSectors(Bit8u subUnit, bool raw, Bit32u sector, Bit16u num, PhysPt data)
|
||||
{
|
||||
void* buffer = (void*)Phys2Host(data);
|
||||
dinfo[subUnit].lastResult = cdrom[subUnit]->ReadSectors(buffer,raw,sector,num);
|
||||
return dinfo[subUnit].lastResult;
|
||||
};
|
||||
|
||||
bool CMscdex::ReadSectorsMSF(Bit8u subUnit, bool raw, Bit32u start, Bit16u num, PhysPt data)
|
||||
{
|
||||
Bit8u min = (start>>16) & 0xFF;
|
||||
Bit8u sec = (start>> 8) & 0xFF;
|
||||
Bit8u fr = (start>> 0) & 0xFF;
|
||||
Bit32u sector = min*60*76+sec*75+fr - 150;
|
||||
// TODO: Check, if num has to be converted too ?!
|
||||
return ReadSectors(subUnit,raw,sector,num,data);
|
||||
};
|
||||
|
||||
bool CMscdex::ReadSectors(Bit16u drive, Bit32u sector, Bit16u num, PhysPt data)
|
||||
// Called from INT 2F
|
||||
{
|
||||
return ReadSectors(GetSubUnit(drive),false,sector,num,data);
|
||||
};
|
||||
|
||||
bool CMscdex::GetCurrentPos(Bit8u subUnit, TMSF& pos)
|
||||
{
|
||||
TMSF rel;
|
||||
Bit8u attr,track,index;
|
||||
dinfo[subUnit].lastResult = GetSubChannelData(subUnit, attr, track, index, rel, pos);
|
||||
if (!dinfo[subUnit].lastResult) memset(&pos,0,sizeof(pos));
|
||||
return dinfo[subUnit].lastResult;
|
||||
};
|
||||
|
||||
bool CMscdex::GetMediaStatus(Bit8u subUnit, bool& media, bool& changed, bool& trayOpen)
|
||||
{
|
||||
dinfo[subUnit].lastResult = cdrom[subUnit]->GetMediaTrayStatus(media,changed,trayOpen);
|
||||
return dinfo[subUnit].lastResult;
|
||||
};
|
||||
|
||||
Bit32u CMscdex::GetDeviceStatus(Bit8u subUnit)
|
||||
{
|
||||
bool media,changed,trayOpen;
|
||||
|
||||
dinfo[subUnit].lastResult = GetMediaStatus(subUnit,media,changed,trayOpen);
|
||||
Bit32u status = (trayOpen << 0) | // Drive is open ?
|
||||
(dinfo[subUnit].locked << 1) | // Drive is locked ?
|
||||
(1<<2) | // raw + cooked sectors
|
||||
(1<<4) | // Can read sudio
|
||||
(1<<9) | // Red book & HSG
|
||||
((!media) << 11); // Drive is empty ?
|
||||
return status;
|
||||
};
|
||||
|
||||
bool CMscdex::GetMediaStatus(Bit8u subUnit, Bit8u& status)
|
||||
{
|
||||
bool media,changed,open,result;
|
||||
result = GetMediaStatus(subUnit,media,changed,open);
|
||||
status = changed ? 0xFF : 0x01;
|
||||
return result;
|
||||
};
|
||||
|
||||
bool CMscdex::LoadUnloadMedia(Bit8u subUnit, bool unload)
|
||||
{
|
||||
dinfo[subUnit].lastResult = cdrom[subUnit]->LoadUnloadMedia(unload);
|
||||
return dinfo[subUnit].lastResult;
|
||||
};
|
||||
|
||||
bool CMscdex::SendDriverRequest(Bit16u drive, PhysPt data)
|
||||
{
|
||||
// Get SubUnit
|
||||
mem_writeb(data+1,GetSubUnit(drive));
|
||||
// Call Strategy / Interrupt
|
||||
MSCDEX_Strategy_Handler();
|
||||
MSCDEX_Interrupt_Handler();
|
||||
return true;
|
||||
};
|
||||
|
||||
Bit16u CMscdex::GetStatusWord(Bit8u subUnit)
|
||||
{
|
||||
Bit16u status ;
|
||||
if (dinfo[subUnit].lastResult) status = REQUEST_STATUS_DONE; // ok
|
||||
else {
|
||||
status = REQUEST_STATUS_ERROR | 0x02; // error : Drive not ready
|
||||
}
|
||||
|
||||
if (dinfo[subUnit].audioPlay) {
|
||||
// Check if audio is still playing....
|
||||
TMSF start,end;
|
||||
bool playing,pause;
|
||||
if (GetAudioStatus(subUnit,playing,pause,start,end)) {
|
||||
dinfo[subUnit].audioPlay = playing;
|
||||
} else
|
||||
dinfo[subUnit].audioPlay = false;
|
||||
|
||||
status |= (dinfo[subUnit].audioPlay<<9);
|
||||
}
|
||||
dinfo[subUnit].lastResult = true;
|
||||
return status;
|
||||
};
|
||||
|
||||
static CMscdex* mscdex = 0;
|
||||
|
||||
static Bitu MSCDEX_Strategy_Handler(void)
|
||||
{
|
||||
// LOG("MSCDEX: Device Strategy Routine called.");
|
||||
return CBRET_NONE;
|
||||
}
|
||||
|
||||
static Bitu MSCDEX_Interrupt_Handler(void)
|
||||
{
|
||||
// LOG("MSCDEX: Device Interrupt Routine called.");
|
||||
|
||||
Bit8u subFuncNr = 0xFF;
|
||||
PhysPt data = PhysMake(SegValue(es),reg_bx);
|
||||
Bit8u subUnit = mem_readb(data+1);
|
||||
Bit8u funcNr = mem_readb(data+2);
|
||||
|
||||
// if (funcNr!=0x03) LOG("MSCDEX: Driver Function %02X",funcNr);
|
||||
|
||||
switch (funcNr) {
|
||||
|
||||
case 0x03 : { /* IOCTL INPUT */
|
||||
PhysPt buffer = PhysMake(mem_readw(data+0x10),mem_readw(data+0x0E));
|
||||
subFuncNr = mem_readb(buffer);
|
||||
//if (subFuncNr!=0x0B) LOG("MSCDEX: IOCTL INPUT Subfunction %02X",subFuncNr);
|
||||
switch (subFuncNr) {
|
||||
case 0x00 : /* Get Device Header address */
|
||||
mem_writed(buffer+1,RealMake(mscdex->rootDriverHeaderSeg,0));
|
||||
break;
|
||||
case 0x01 :{/* Get current position */
|
||||
TMSF pos;
|
||||
mscdex->GetCurrentPos(subUnit,pos);
|
||||
mem_writeb(buffer+1,0x01); // Red book
|
||||
mem_writeb(buffer+2,pos.fr);
|
||||
mem_writeb(buffer+3,pos.sec);
|
||||
mem_writeb(buffer+4,pos.min);
|
||||
mem_writeb(buffer+5,0x00);
|
||||
}break;
|
||||
case 0x06 : /* Get Device status */
|
||||
mem_writed(buffer+1,mscdex->GetDeviceStatus(subUnit));
|
||||
break;
|
||||
case 0x07 : /* Get sector size */
|
||||
if (mem_readb(buffer+1)==0x01) mem_writed(buffer+2,2352);
|
||||
else mem_writed(buffer+2,2048);
|
||||
break;
|
||||
case 0x08 : /* Get size of current volume */
|
||||
mem_writed(buffer+1,mscdex->GetVolumeSize(subUnit));
|
||||
break;
|
||||
case 0x09 : /* Media change ? */
|
||||
Bit8u status;
|
||||
mscdex->GetMediaStatus(subUnit,status);
|
||||
mem_writeb(buffer+1,status);
|
||||
break;
|
||||
case 0x0A : /* Get Audio Disk info */
|
||||
Bit8u tr1,tr2; TMSF leadOut;
|
||||
mscdex->GetCDInfo(subUnit,tr1,tr2,leadOut);
|
||||
mem_writeb(buffer+1,tr1);
|
||||
mem_writeb(buffer+2,tr2);
|
||||
mem_writeb(buffer+3,leadOut.fr);
|
||||
mem_writeb(buffer+4,leadOut.sec);
|
||||
mem_writeb(buffer+5,leadOut.min);
|
||||
mem_writeb(buffer+6,0x00);
|
||||
break;
|
||||
case 0x0B :{/* Audio Track Info */
|
||||
Bit8u attr; TMSF start;
|
||||
Bit8u track = mem_readb(buffer+1);
|
||||
mscdex->GetTrackInfo(subUnit,track,attr,start);
|
||||
mem_writeb(buffer+2,start.fr);
|
||||
mem_writeb(buffer+3,start.sec);
|
||||
mem_writeb(buffer+4,start.min);
|
||||
mem_writeb(buffer+5,0x00);
|
||||
mem_writeb(buffer+6,attr);
|
||||
break; };
|
||||
case 0x0C :{/* Get Audio Sub Channel data */
|
||||
Bit8u attr,track,index;
|
||||
TMSF abs,rel;
|
||||
mscdex->GetSubChannelData(subUnit,attr,track,index,rel,abs);
|
||||
mem_writeb(buffer+1,attr);
|
||||
mem_writeb(buffer+2,track);
|
||||
mem_writeb(buffer+3,index);
|
||||
mem_writeb(buffer+4,rel.min);
|
||||
mem_writeb(buffer+5,rel.sec);
|
||||
mem_writeb(buffer+6,rel.fr);
|
||||
mem_writeb(buffer+7,0x00);
|
||||
mem_writeb(buffer+8,abs.min);
|
||||
mem_writeb(buffer+9,abs.sec);
|
||||
mem_writeb(buffer+10,abs.fr);
|
||||
break;
|
||||
};
|
||||
case 0x0E :{ /* Get UPC */
|
||||
Bit8u attr; char upc[8];
|
||||
mscdex->GetUPC(subUnit,attr,&upc[0]);
|
||||
mem_writeb(buffer+1,attr);
|
||||
for (int i=0; i<7; i++) mem_writeb(buffer+2+i,upc[i]);
|
||||
mem_writeb(buffer+9,0x00);
|
||||
break;
|
||||
};
|
||||
case 0x0F :{ /* Get Audio Status */
|
||||
bool playing,pause;
|
||||
TMSF resStart,resEnd;
|
||||
mscdex->GetAudioStatus(subUnit,playing,pause,resStart,resEnd);
|
||||
mem_writeb(buffer+1,pause);
|
||||
mem_writeb(buffer+3,resStart.min);
|
||||
mem_writeb(buffer+4,resStart.sec);
|
||||
mem_writeb(buffer+5,resStart.fr);
|
||||
mem_writeb(buffer+6,0x00);
|
||||
mem_writeb(buffer+7,resEnd.min);
|
||||
mem_writeb(buffer+8,resEnd.sec);
|
||||
mem_writeb(buffer+9,resEnd.fr);
|
||||
mem_writeb(buffer+10,0x00);
|
||||
break;
|
||||
};
|
||||
default : LOG(LOG_ERROR|LOG_MISC,"MSCDEX: Unsupported IOCTL INPUT Subfunction %02X",subFuncNr);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
};
|
||||
case 0x0C : { /* IOCTL OUTPUT */
|
||||
PhysPt buffer = PhysMake(mem_readw(data+0x10),mem_readw(data+0x0E));
|
||||
subFuncNr = mem_readb(buffer);
|
||||
// if (subFuncNr!=0x0B) LOG("MSCDEX: IOCTL OUTPUT Subfunction %02X",subFuncNr);
|
||||
switch (subFuncNr) {
|
||||
case 0x00 : // Unload /eject) media
|
||||
mscdex->LoadUnloadMedia(subUnit,true);
|
||||
break;
|
||||
case 0x01 : // (un)Lock door
|
||||
// do nothing -> report as success
|
||||
break;
|
||||
case 0x05 : // load media
|
||||
mscdex->LoadUnloadMedia(subUnit,false);
|
||||
break;
|
||||
default : LOG(LOG_ERROR|LOG_MISC,"MSCDEX: Unsupported IOCTL OUTPUT Subfunction %02X",subFuncNr);
|
||||
break;
|
||||
};
|
||||
break;
|
||||
};
|
||||
case 0x0D : // device open
|
||||
case 0x0E : // device close - dont care :)
|
||||
break;
|
||||
case 0x80 : // Read long
|
||||
case 0x82 : { // Read long prefetch -> both the same here :)
|
||||
PhysPt buff = PhysMake(mem_readw(data+0x10),mem_readw(data+0x0E));
|
||||
Bit32u start = mem_readd(data+0x14);
|
||||
Bit16u len = mem_readw(data+0x12);
|
||||
bool raw = (mem_readb(data+0x18)==1);
|
||||
if (mem_readb(data+0x0D)==0x00) // HSG
|
||||
mscdex->ReadSectors(subUnit,raw,start,len,buff);
|
||||
else
|
||||
mscdex->ReadSectorsMSF(subUnit,raw,start,len,buff);
|
||||
break;
|
||||
};
|
||||
case 0x83 : // Seek - dont care :)
|
||||
break;
|
||||
case 0x84 : { /* Play Audio Sectors */
|
||||
Bit32u start = mem_readd(data+0x0E);
|
||||
Bit32u len = mem_readd(data+0x12);
|
||||
if (mem_readb(data+0x0D)==0x00) // HSG
|
||||
mscdex->PlayAudioSector(subUnit,start,len);
|
||||
else // RED BOOK
|
||||
mscdex->PlayAudioMSF(subUnit,start,len);
|
||||
break;
|
||||
};
|
||||
case 0x85 : /* Stop Audio */
|
||||
mscdex->StopAudio(subUnit);
|
||||
break;
|
||||
case 0x88 : /* Resume Audio */
|
||||
mscdex->ResumeAudio(subUnit);
|
||||
break;
|
||||
default : LOG(LOG_ERROR|LOG_MISC,"MSCDEX: Unsupported Driver Request %02X",funcNr);
|
||||
break;
|
||||
|
||||
};
|
||||
|
||||
// Set Statusword
|
||||
mem_writew(data+3,mscdex->GetStatusWord(subUnit));
|
||||
return CBRET_NONE;
|
||||
}
|
||||
|
||||
static bool MSCDEX_Handler(void)
|
||||
{
|
||||
if (reg_ah!=0x15) return false;
|
||||
|
||||
PhysPt data = PhysMake(SegValue(es),reg_bx);
|
||||
// if (reg_ax!=0x1510) LOG("MSCEEX: INT 2F %04X",reg_ax);
|
||||
switch (reg_ax) {
|
||||
|
||||
case 0x1500: /* Install check */
|
||||
reg_bx = mscdex->GetNumDrives();
|
||||
if (reg_bx>0) reg_cx = mscdex->GetFirstDrive();
|
||||
return true;
|
||||
case 0x1501: /* Get cdrom driver info */
|
||||
mscdex->GetDriverInfo(data);
|
||||
return true;
|
||||
case 0x1502: /* Get Copyright filename */
|
||||
if (mscdex->GetCopyrightName(reg_cx,data)) {
|
||||
CALLBACK_SCF(false);
|
||||
} else {
|
||||
reg_al = MSCDEX_ERROR_UNKNOWN_DRIVE;
|
||||
CALLBACK_SCF(true);
|
||||
};
|
||||
return true;
|
||||
case 0x1503: /* Get Abstract filename */
|
||||
if (mscdex->GetAbstractName(reg_cx,data)) {
|
||||
CALLBACK_SCF(false);
|
||||
} else {
|
||||
reg_al = MSCDEX_ERROR_UNKNOWN_DRIVE;
|
||||
CALLBACK_SCF(true);
|
||||
};
|
||||
return true;
|
||||
case 0x1504: /* Get Documentation filename */
|
||||
if (mscdex->GetDocumentationName(reg_cx,data)) {
|
||||
CALLBACK_SCF(false);
|
||||
} else {
|
||||
reg_al = MSCDEX_ERROR_UNKNOWN_DRIVE;
|
||||
CALLBACK_SCF(true);
|
||||
};
|
||||
return true;
|
||||
/* case 0x1505: { // read vtoc
|
||||
Bit16u error = 0;
|
||||
if (mscdex->ReadVTOC(reg_cx,reg_dx,data,error)) {
|
||||
CALLBACK_SCF(false);
|
||||
} else {
|
||||
reg_ax = error;
|
||||
CALLBACK_SCF(true);
|
||||
};
|
||||
};
|
||||
return true;*/
|
||||
case 0x1508: { // read sectors
|
||||
Bit32u sector = (reg_si<<16)+reg_di;
|
||||
if (mscdex->ReadSectors(reg_cx,sector,reg_dx,data)) {
|
||||
CALLBACK_SCF(false);
|
||||
} else {
|
||||
reg_al = MSCDEX_ERROR_UNKNOWN_DRIVE;
|
||||
CALLBACK_SCF(true);
|
||||
};
|
||||
return true;
|
||||
};
|
||||
case 0x1509: // write sectors - not supported
|
||||
reg_al = MSCDEX_ERROR_DRIVE_NOT_READY;
|
||||
CALLBACK_SCF(true);
|
||||
return true;
|
||||
case 0x150B: /* Valid CDROM drive ? */
|
||||
reg_ax = mscdex->IsValidDrive(reg_cx);
|
||||
reg_bx = 0xADAD;
|
||||
return true;
|
||||
case 0x150C: /* Get MSCDEX Version */
|
||||
reg_bx = mscdex->GetVersion();
|
||||
return true;
|
||||
case 0x150D: /* Get drives */
|
||||
mscdex->GetDrives(data);
|
||||
return true;
|
||||
case 0x1510: /* Device driver request */
|
||||
mscdex->SendDriverRequest(reg_cx,data);
|
||||
return true;
|
||||
default : LOG(LOG_ERROR|LOG_MISC,"MSCDEX: Unknwon call : %04X",reg_ax);
|
||||
return true;
|
||||
|
||||
};
|
||||
return false;
|
||||
};
|
||||
|
||||
class device_MSCDEX : public DOS_Device {
|
||||
public:
|
||||
device_MSCDEX() { name="MSCD001"; }
|
||||
bool Read (Bit8u * data,Bit16u * size) { return false;}
|
||||
bool Write(Bit8u * data,Bit16u * size) {
|
||||
LOG(0,"Write to mscdex device");
|
||||
return false;
|
||||
}
|
||||
bool Seek(Bit32u * pos,Bit32u type){return false;}
|
||||
bool Close(){return false;}
|
||||
Bit16u GetInformation(void){return 0x8093;}
|
||||
private:
|
||||
Bit8u cache;
|
||||
};
|
||||
|
||||
int MSCDEX_AddDrive(char driveLetter, const char* physicalPath, Bit8u& subUnit)
|
||||
{
|
||||
int result = mscdex->AddDrive(driveLetter-'A',(char*)physicalPath,subUnit);
|
||||
return result;
|
||||
};
|
||||
|
||||
bool MSCDEX_HasMediaChanged(Bit8u subUnit)
|
||||
{
|
||||
static TMSF leadOut[MSCDEX_MAX_DRIVES];
|
||||
|
||||
TMSF leadnew;
|
||||
Bit8u tr1,tr2;
|
||||
if (mscdex->GetCDInfo(subUnit,tr1,tr2,leadnew)) {
|
||||
bool changed = (leadOut[subUnit].min!=leadnew.min) || (leadOut[subUnit].sec!=leadnew.sec) || (leadOut[subUnit].fr!=leadnew.fr);
|
||||
leadOut[subUnit].min = leadnew.min;
|
||||
leadOut[subUnit].sec = leadnew.sec;
|
||||
leadOut[subUnit].fr = leadnew.fr;
|
||||
return changed;
|
||||
};
|
||||
if (subUnit<MSCDEX_MAX_DRIVES) {
|
||||
leadOut[subUnit].min = 0;
|
||||
leadOut[subUnit].sec = 0;
|
||||
leadOut[subUnit].fr = 0;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
void MSCDEX_SetCDInterface(int intNr, int numCD)
|
||||
{
|
||||
useCdromInterface = intNr;
|
||||
forceCD = numCD;
|
||||
};
|
||||
|
||||
void MSCDEX_ShutDown(Section* sec)
|
||||
{
|
||||
delete mscdex; mscdex = 0;
|
||||
};
|
||||
|
||||
void MSCDEX_Init(Section* sec)
|
||||
{
|
||||
// AddDestroy func
|
||||
sec->AddDestroyFunction(&MSCDEX_ShutDown);
|
||||
/* Register the mscdex device */
|
||||
DOS_Device * newdev = new device_MSCDEX();
|
||||
DOS_AddDevice(newdev);
|
||||
/* Add Multiplexer */
|
||||
DOS_AddMultiplexHandler(MSCDEX_Handler);
|
||||
/* Create MSCDEX */
|
||||
mscdex = new CMscdex;
|
||||
};
|
||||
|
@ -25,14 +25,27 @@
|
||||
#include "cross.h"
|
||||
#include "regs.h"
|
||||
#include "callback.h"
|
||||
#include "cdrom.h"
|
||||
#include "../shell/shell_inc.h"
|
||||
|
||||
void MSCDEX_SetCDInterface(int intNr, int forceCD);
|
||||
|
||||
class MOUNT : public Program {
|
||||
public:
|
||||
void Run(void)
|
||||
{
|
||||
DOS_Drive * newdrive;char drive;
|
||||
|
||||
// Show list of cdroms
|
||||
if (cmd->FindExist("-cd",false)) {
|
||||
int num = SDL_CDNumDrives();
|
||||
WriteOut("CDROMs found: %d\n",num);
|
||||
for (int i=0; i<num; i++) {
|
||||
WriteOut("%2d. %s\n",i,SDL_CDName(i));
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
/* Parse the command line */
|
||||
/* if the command line is empty show current mounts */
|
||||
if (!cmd->GetCount()) {
|
||||
@ -44,9 +57,10 @@ public:
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
std::string type="dir";
|
||||
cmd->FindString("-t",type,true);
|
||||
if (type=="floppy" || type=="dir") {
|
||||
if (type=="floppy" || type=="dir" || type=="cdrom") {
|
||||
Bit16u sizes[4];
|
||||
Bit8u mediaid;
|
||||
std::string str_size;
|
||||
@ -58,6 +72,10 @@ public:
|
||||
str_size="512,127,16513,1700";
|
||||
mediaid=0xF8; /* Hard Disk */
|
||||
}
|
||||
if (type=="cdrom") {
|
||||
str_size="650,127,16513,1700";
|
||||
mediaid=0xF8; /* Hard Disk */
|
||||
}
|
||||
cmd->FindString("-size",str_size,true);
|
||||
char number[20];const char * scan=str_size.c_str();
|
||||
Bitu index=0;Bitu count=0;
|
||||
@ -70,7 +88,12 @@ public:
|
||||
scan++;
|
||||
}
|
||||
number[index]=0;sizes[count++]=atoi(number);
|
||||
|
||||
|
||||
// get the drive letter
|
||||
cmd->FindCommand(1,temp_line);
|
||||
if ((temp_line.size() > 2) || ((temp_line.size()>1) && (temp_line[1]!=':'))) goto showusage;
|
||||
drive=toupper(temp_line[0]);
|
||||
if (!isalpha(drive)) goto showusage;
|
||||
|
||||
if (!cmd->FindCommand(2,temp_line)) goto showusage;
|
||||
if (!temp_line.size()) goto showusage;
|
||||
@ -86,14 +109,30 @@ public:
|
||||
}
|
||||
if (temp_line[temp_line.size()-1]!=CROSS_FILESPLIT) temp_line+=CROSS_FILESPLIT;
|
||||
Bit8u bit8size=(Bit8u) sizes[1];
|
||||
newdrive=new localDrive(temp_line.c_str(),sizes[0],bit8size,sizes[2],sizes[3],mediaid);
|
||||
if (type=="cdrom") {
|
||||
int num = -1;
|
||||
cmd->FindInt("-usecd",num,true);
|
||||
int error;
|
||||
if (cmd->FindExist("-aspi",false)) MSCDEX_SetCDInterface(CDROM_USE_ASPI, num); else
|
||||
if (cmd->FindExist("-ioctl",false)) MSCDEX_SetCDInterface(CDROM_USE_IOCTL, num);
|
||||
else MSCDEX_SetCDInterface(CDROM_USE_SDL, num);
|
||||
newdrive = new cdromDrive(drive,temp_line.c_str(),sizes[0],bit8size,sizes[2],0,mediaid,error);
|
||||
// Check Mscdex, if it worked out...
|
||||
switch (error) {
|
||||
case 0 : WriteOut(MSG_Get("MSCDEX_SUCCESS")); break;
|
||||
case 1 : WriteOut(MSG_Get("MSCDEX_ERROR_MULTIPLE_CDROMS")); break;
|
||||
case 2 : WriteOut(MSG_Get("MSCDEX_ERROR_NOT_SUPPORTED")); break;
|
||||
case 3 : WriteOut(MSG_Get("MSCDEX_ERROR_PATH")); break;
|
||||
case 4 : WriteOut(MSG_Get("MSCDEX_TOO_MANY_DRIVES")); break;
|
||||
case 5 : WriteOut(MSG_Get("MSCDEX_LIMITED_SUPPORT")); break;
|
||||
default : WriteOut(MSG_Get("MSCDEX_UNKNOWN_ERROR")); break;
|
||||
};
|
||||
} else {
|
||||
newdrive=new localDrive(temp_line.c_str(),sizes[0],bit8size,sizes[2],sizes[3],mediaid);
|
||||
}
|
||||
}
|
||||
cmd->FindCommand(1,temp_line);
|
||||
if (temp_line.size()>1) goto showusage;
|
||||
drive=toupper(temp_line[0]);
|
||||
if (!isalpha(drive)) goto showusage;
|
||||
if (Drives[drive-'A']) {
|
||||
WriteOut(MSG_Get("PROGRAM_MOUNT_ALLREADY_MOUNDTED"),drive,Drives[drive-'A']->GetInfo());
|
||||
WriteOut(MSG_Get("PROGRAM_MOUNT_ALLREADY_MOUNTED"),drive,Drives[drive-'A']->GetInfo());
|
||||
if (newdrive) delete newdrive;
|
||||
return;
|
||||
}
|
||||
@ -149,78 +188,6 @@ static void MEM_ProgramStart(Program * * make) {
|
||||
}
|
||||
|
||||
|
||||
#if !defined (WIN32) /* Unix */
|
||||
|
||||
class UPCASE : public Program {
|
||||
public:
|
||||
void Run(void);
|
||||
void upcasedir(const char * directory);
|
||||
};
|
||||
|
||||
void UPCASE::upcasedir(const char * directory) {
|
||||
DIR * sdir;
|
||||
char fullname[512];
|
||||
char newname[512];
|
||||
struct dirent *tempdata;
|
||||
struct stat finfo;
|
||||
|
||||
if(!(sdir=opendir(directory))) {
|
||||
WriteOut(MSG_Get("PROGRAM_UPCASE_ERROR_DIR"),directory);
|
||||
return;
|
||||
}
|
||||
WriteOut(MSG_Get("PROGRAM_UPCASE_SCANNING_DIR"),fullname);
|
||||
while (tempdata=readdir(sdir)) {
|
||||
if (strcmp(tempdata->d_name,".")==0) continue;
|
||||
if (strcmp(tempdata->d_name,"..")==0) continue;
|
||||
strcpy(fullname,directory);
|
||||
strcat(fullname,"/");
|
||||
strcat(fullname,tempdata->d_name);
|
||||
strcpy(newname,directory);
|
||||
strcat(newname,"/");
|
||||
upcase(tempdata->d_name);
|
||||
strcat(newname,tempdata->d_name);
|
||||
WriteOut(MSG_Get("PROGRAM_UPCASE_RENAME"),fullname,newname);
|
||||
rename(fullname,newname);
|
||||
stat(fullname,&finfo);
|
||||
if(S_ISDIR(finfo.st_mode)) {
|
||||
upcasedir(fullname);
|
||||
}
|
||||
}
|
||||
closedir(sdir);
|
||||
}
|
||||
|
||||
|
||||
void UPCASE::Run(void) {
|
||||
/* First check if the directory exists */
|
||||
struct stat info;
|
||||
WriteOut(MSG_Get("PROGRAM_UPCASE_RUN_1"));
|
||||
if (!cmd->GetCount()) {
|
||||
WriteOut(MSG_Get("PROGRAM_UPCASE_USAGE"));
|
||||
return;
|
||||
}
|
||||
cmd->FindCommand(1,temp_line);
|
||||
if (stat(temp_line.c_str(),&info)) {
|
||||
WriteOut(MSG_Get("PROGRAM_UPCASE_RUN_ERROR_1"),temp_line.c_str());
|
||||
return;
|
||||
}
|
||||
if(!S_ISDIR(info.st_mode)) {
|
||||
WriteOut(MSG_Get("PROGRAM_UPCASE_RUN_ERROR_2"),temp_line.c_str());
|
||||
return;
|
||||
}
|
||||
WriteOut(MSG_Get("PROGRAM_UPCASE_RUN_CHOICE"),temp_line.c_str());
|
||||
Bit8u key;Bit16u n=1;
|
||||
DOS_ReadFile(STDIN,&key,&n);
|
||||
if (toupper(key)=='Y') {
|
||||
upcasedir(temp_line.c_str());
|
||||
} else {
|
||||
WriteOut(MSG_Get("PROGRAM_UPCASE_RUN_NO"));
|
||||
}
|
||||
}
|
||||
|
||||
static void UPCASE_ProgramStart(Program * * make) {
|
||||
*make=new UPCASE;
|
||||
}
|
||||
#endif
|
||||
|
||||
// LOADFIX
|
||||
|
||||
@ -253,8 +220,8 @@ void LOADFIX::Run(void)
|
||||
Bit16u segment;
|
||||
Bit16u blocks = kb*1024/16;
|
||||
if (DOS_AllocateMemory(&segment,&blocks)) {
|
||||
MCB* pmcb = (MCB*)HostMake(segment-1,0);
|
||||
pmcb->psp_segment = 0x40; // use fake segment
|
||||
DOS_MCB mcb((Bit16u)(segment-1));
|
||||
mcb.SetPSPSeg(0x40); // use fake segment
|
||||
WriteOut(MSG_Get("PROGRAM_LOADFIX_ALLOC"),kb);
|
||||
// Prepare commandline...
|
||||
if (cmd->FindCommand(commandNr++,temp_line)) {
|
||||
@ -285,6 +252,38 @@ static void LOADFIX_ProgramStart(Program * * make) {
|
||||
*make=new LOADFIX;
|
||||
}
|
||||
|
||||
// RESCAN
|
||||
|
||||
class RESCAN : public Program {
|
||||
public:
|
||||
void Run(void);
|
||||
};
|
||||
|
||||
void RESCAN::Run(void)
|
||||
{
|
||||
// Get current drive
|
||||
Bit8u drive = DOS_GetDefaultDrive();
|
||||
if (Drives[drive]) {
|
||||
Drives[drive]->EmptyCache();
|
||||
WriteOut(MSG_Get("PROGRAM_RESCAN_SUCCESS"));
|
||||
}
|
||||
};
|
||||
|
||||
static void RESCAN_ProgramStart(Program * * make) {
|
||||
*make=new RESCAN;
|
||||
}
|
||||
|
||||
class INTRO : public Program {
|
||||
public:
|
||||
void Run(void) {
|
||||
WriteOut(MSG_Get("PROGRAM_INTRO"));
|
||||
}
|
||||
};
|
||||
|
||||
static void INTRO_ProgramStart(Program * * make) {
|
||||
*make=new INTRO;
|
||||
}
|
||||
|
||||
void DOS_SetupPrograms(void) {
|
||||
/*Add Messages */
|
||||
MSG_Add("PROGRAM_MOUNT_STATUS_2","Drive %c is mounted as %s\n");
|
||||
@ -303,22 +302,42 @@ void DOS_SetupPrograms(void) {
|
||||
MSG_Add("PROGRAM_LOADFIX_DEALLOCALL","Used memory freed.\n");
|
||||
MSG_Add("PROGRAM_LOADFIX_ERROR","Memory allocation error.\n");
|
||||
|
||||
#if !defined (WIN32) /* Unix */
|
||||
MSG_Add("PROGRAM_UPCASE_ERROR_DIR","Failed to open directory %s\n");
|
||||
MSG_Add("PROGRAM_UPCASE_SCANNING_DIR","Scanning directory %s\n");
|
||||
MSG_Add("PROGRAM_UPCASE_RENAME","Renaming %s to %s\n");
|
||||
MSG_Add("PROGRAM_UPCASE_RUN_1","UPCASE 0.1 Directory case convertor.\n");
|
||||
MSG_Add("PROGRAM_UPCASE_USAGE","Usage UPCASE [local directory]\nThis tool will convert all files and subdirectories in a directory.\nBe VERY sure this directory contains only dos related material.\nOtherwise you might horribly screw up your filesystem.\n");
|
||||
MSG_Add("PROGRAM_UPCASE_RUN_ERROR_1","%s doesn't exist\n");
|
||||
MSG_Add("PROGRAM_UPCASE_RUN_ERROR_2","%s isn't a directory\n");
|
||||
MSG_Add("PROGRAM_UPCASE_RUN_CHOICE","Converting the wrong directories can be very harmfull, please be carefull.\nAre you really really sure you want to convert %s to upcase?Y/N\n");
|
||||
MSG_Add("PROGRAM_UPCASE_RUN_NO","Okay better not do it.\n");
|
||||
#endif
|
||||
MSG_Add("MSCDEX_SUCCESS","MSCDEX installed.\n");
|
||||
MSG_Add("MSCDEX_ERROR_MULTIPLE_CDROMS","MSCDEX: Failure: Drive-letters of multiple CDRom-drives have to be continuous.\n");
|
||||
MSG_Add("MSCDEX_ERROR_NOT_SUPPORTED","MSCDEX: Failure: Not yet supported.\n");
|
||||
MSG_Add("MSCDEX_ERROR_PATH","MSCDEX: Failure: Path not valid.\n");
|
||||
MSG_Add("MSCDEX_TOO_MANY_DRIVES","MSCDEX: Failure: Too many CDRom-drives (max: 5). MSCDEX Installation failed.\n");
|
||||
MSG_Add("MSCDEX_LIMITED_SUPPORT","MSCDEX: Mounted subdirectory: limited support.\n");
|
||||
MSG_Add("MSCDEX_UNKNOWN_ERROR","MSCDEX: Failure: Unknown error.\n");
|
||||
|
||||
MSG_Add("PROGRAM_RESCAN_SUCCESS","Drive cache cleared.\n");
|
||||
|
||||
MSG_Add("PROGRAM_INTRO",
|
||||
"Welcome to DOSBox, an x86 emulator with sound and graphics.\n"
|
||||
"DOSBox creates a shell for you which looks like old plain DOS.\n"
|
||||
"\n"
|
||||
"Here are some commands to get you started:\n"
|
||||
"Before you can use the files located on your own filesystem,\n"
|
||||
"You have to mount the directory containing the files.\n"
|
||||
"For Windows:\n"
|
||||
"mount c c:\\dosprog will create a C drive in dosbox with c:\\dosprog as contents.\n"
|
||||
"\n"
|
||||
"For other platfroms:\n"
|
||||
"mount c /home/user/dosprog will do the same.\n"
|
||||
"\n"
|
||||
"When the mount has succesfully completed you can type c: to go to your freshly\n"
|
||||
"mounted C-drive. Typing dir there will show its contents. cd will allow you to\n"
|
||||
"enter a directory (recognised by the [] in a directory listing).\n"
|
||||
"You can run programs/files which end with .exe .bat and .com .\n"
|
||||
|
||||
"\n"
|
||||
"DOSBox will stop/exit without a warning if an error occured!\n"
|
||||
);
|
||||
|
||||
/*regular setup*/
|
||||
PROGRAMS_MakeFile("MOUNT.COM",MOUNT_ProgramStart);
|
||||
PROGRAMS_MakeFile("MEM.COM",MEM_ProgramStart);
|
||||
PROGRAMS_MakeFile("LOADFIX.COM",LOADFIX_ProgramStart);
|
||||
#if !defined (WIN32) /* Unix */
|
||||
PROGRAMS_MakeFile("UPCASE.COM",UPCASE_ProgramStart);
|
||||
#endif
|
||||
PROGRAMS_MakeFile("RESCAN.COM",RESCAN_ProgramStart);
|
||||
PROGRAMS_MakeFile("INTRO.COM",INTRO_ProgramStart);
|
||||
}
|
||||
|
635
src/dos/drive_cache.cpp
Normal file
635
src/dos/drive_cache.cpp
Normal file
@ -0,0 +1,635 @@
|
||||
|
||||
/*
|
||||
* Copyright (C) 2002-2003 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "drives.h"
|
||||
#include "dos_inc.h"
|
||||
#include "dirent.h"
|
||||
#include "support.h"
|
||||
|
||||
// STL stuff
|
||||
#include <vector>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
|
||||
|
||||
bool SortByName(DOS_Drive_Cache::CFileInfo* const &a, DOS_Drive_Cache::CFileInfo* const &b)
|
||||
{
|
||||
return strcmp(a->shortname,b->shortname)<0;
|
||||
};
|
||||
|
||||
bool SortByNameRev(DOS_Drive_Cache::CFileInfo* const &a, DOS_Drive_Cache::CFileInfo* const &b)
|
||||
{
|
||||
return strcmp(a->shortname,b->shortname)>0;
|
||||
};
|
||||
|
||||
bool SortByDirName(DOS_Drive_Cache::CFileInfo* const &a, DOS_Drive_Cache::CFileInfo* const &b)
|
||||
{
|
||||
// Directories first...
|
||||
if (a->isDir!=b->isDir) return (a->isDir>b->isDir);
|
||||
return strcmp(a->shortname,b->shortname)<0;
|
||||
};
|
||||
|
||||
bool SortByDirNameRev(DOS_Drive_Cache::CFileInfo* const &a, DOS_Drive_Cache::CFileInfo* const &b)
|
||||
{
|
||||
// Directories first...
|
||||
if (a->isDir!=b->isDir) return (a->isDir>b->isDir);
|
||||
return strcmp(a->shortname,b->shortname)>0;
|
||||
};
|
||||
|
||||
DOS_Drive_Cache::DOS_Drive_Cache(void)
|
||||
{
|
||||
dirBase = new CFileInfo;
|
||||
save_dir = 0;
|
||||
srchNr = 0;
|
||||
for (Bit32u i=0; i<MAX_OPENDIRS; i++) { dirSearch[i] = 0; free[i] = true; };
|
||||
SetDirSort(DIRALPHABETICAL);
|
||||
|
||||
};
|
||||
|
||||
DOS_Drive_Cache::DOS_Drive_Cache(const char* path)
|
||||
{
|
||||
dirBase = new CFileInfo;
|
||||
save_dir = 0;
|
||||
srchNr = 0;
|
||||
for (Bit32u i=0; i<MAX_OPENDIRS; i++) { dirSearch[i] = 0; free[i] = true; };
|
||||
SetDirSort(DIRALPHABETICAL);
|
||||
SetBaseDir(path);
|
||||
};
|
||||
|
||||
DOS_Drive_Cache::~DOS_Drive_Cache(void)
|
||||
{
|
||||
Clear();
|
||||
};
|
||||
|
||||
void DOS_Drive_Cache::Clear(void)
|
||||
{
|
||||
delete dirBase; dirBase = 0;
|
||||
for (Bit32u i=0; i<MAX_OPENDIRS; i++) dirSearch[i] = 0;
|
||||
};
|
||||
|
||||
void DOS_Drive_Cache::EmptyCache(void)
|
||||
{
|
||||
// Empty Cache and reinit
|
||||
Clear();
|
||||
dirBase = new CFileInfo;
|
||||
save_dir = 0;
|
||||
srchNr = 0;
|
||||
for (Bit32u i=0; i<MAX_OPENDIRS; i++) free[i] = true;
|
||||
SetBaseDir(basePath);
|
||||
};
|
||||
|
||||
Bit16u DOS_Drive_Cache::GetFreeID(CFileInfo* dir)
|
||||
{
|
||||
for (Bit32u i=0; i<MAX_OPENDIRS; i++) if (free[i] || (dir==dirSearch[i])) return i;
|
||||
LOG(LOG_FILES,"DIRCACHE: Too many open directories!");
|
||||
return 0;
|
||||
};
|
||||
|
||||
void DOS_Drive_Cache::SetBaseDir(const char* baseDir)
|
||||
{
|
||||
Bit16u id;
|
||||
strcpy(basePath,baseDir);
|
||||
if (OpenDir(baseDir,id)) {
|
||||
char * result;
|
||||
ReadDir(id,result);
|
||||
};
|
||||
};
|
||||
|
||||
void DOS_Drive_Cache::ExpandName(char* path)
|
||||
{
|
||||
strcpy(path,GetExpandName(path));
|
||||
};
|
||||
|
||||
char* DOS_Drive_Cache::GetExpandName(const char* path)
|
||||
{
|
||||
static char work [CROSS_LEN];
|
||||
char dir [CROSS_LEN];
|
||||
|
||||
work[0] = 0;
|
||||
strcpy (dir,path);
|
||||
|
||||
char* pos = strrchr(path,CROSS_FILESPLIT);
|
||||
|
||||
if (pos) dir[pos-path+1] = 0;
|
||||
CFileInfo* dirInfo = FindDirInfo(dir, work);
|
||||
|
||||
if (pos) {
|
||||
// Last Entry = File
|
||||
strcpy(dir,pos+1);
|
||||
GetLongName(dirInfo, dir);
|
||||
strcat(work,dir);
|
||||
}
|
||||
return work;
|
||||
};
|
||||
|
||||
void DOS_Drive_Cache::AddEntry(const char* path, bool checkExists)
|
||||
{
|
||||
// Get Last part...
|
||||
char file [CROSS_LEN];
|
||||
char expand [CROSS_LEN];
|
||||
|
||||
CFileInfo* dir = FindDirInfo(path,expand);
|
||||
char* pos = strrchr(path,CROSS_FILESPLIT);
|
||||
|
||||
if (pos) {
|
||||
strcpy(file,pos+1);
|
||||
// Check if file already exists, then dont add new entry...
|
||||
if (checkExists && (GetLongName(dir,file)>=0)) return;
|
||||
|
||||
CreateEntry(dir,file);
|
||||
// Sort Lists - filelist has to be alphabetically sorted
|
||||
std::sort(dir->fileList.begin(), dir->fileList.end(), SortByName);
|
||||
// Output list - user defined
|
||||
switch (sortDirType) {
|
||||
case ALPHABETICAL : std::sort(dir->outputList.begin(), dir->outputList.end(), SortByName); break;
|
||||
case DIRALPHABETICAL : std::sort(dir->outputList.begin(), dir->outputList.end(), SortByDirName); break;
|
||||
case ALPHABETICALREV : std::sort(dir->outputList.begin(), dir->outputList.end(), SortByNameRev); break;
|
||||
case DIRALPHABETICALREV : std::sort(dir->outputList.begin(), dir->outputList.end(), SortByDirNameRev); break;
|
||||
case NOSORT : break;
|
||||
};
|
||||
|
||||
Bit16s index = GetLongName(dir,file);
|
||||
if (index>=0) {
|
||||
Bit32u i;
|
||||
// Check if there are any open search dir that are affected by this...
|
||||
if (dir) for (i=0; i<MAX_OPENDIRS; i++) {
|
||||
if ((dirSearch[i]==dir) && (index<=dirSearch[i]->nextEntry))
|
||||
dirSearch[i]->nextEntry++;
|
||||
}
|
||||
};
|
||||
// LOG_DEBUG("DIR: Added Entry %s",path);
|
||||
} else {
|
||||
// LOG_DEBUG("DIR: Error: Failed to add %s",path);
|
||||
};
|
||||
};
|
||||
|
||||
void DOS_Drive_Cache::DeleteEntry(const char* path, bool ignoreLastDir)
|
||||
{
|
||||
CacheOut(path,ignoreLastDir);
|
||||
if (dirSearch[srchNr]->nextEntry>0) dirSearch[srchNr]->nextEntry--;
|
||||
|
||||
if (!ignoreLastDir) {
|
||||
// Check if there are any open search dir that are affected by this...
|
||||
Bit32u i;
|
||||
char expand [CROSS_LEN];
|
||||
CFileInfo* dir = FindDirInfo(path,expand);
|
||||
if (dir) for (i=0; i<MAX_OPENDIRS; i++) {
|
||||
if ((dirSearch[i]==dir) && (dirSearch[i]->nextEntry>0))
|
||||
dirSearch[i]->nextEntry--;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void DOS_Drive_Cache::CacheOut(const char* path, bool ignoreLastDir)
|
||||
{
|
||||
char expand[CROSS_LEN] = { 0 };
|
||||
CFileInfo* dir;
|
||||
|
||||
if (ignoreLastDir) {
|
||||
char tmp[CROSS_LEN] = { 0 };
|
||||
Bit32s len = strrchr(path,CROSS_FILESPLIT) - path;
|
||||
if (len>0) {
|
||||
strncpy(tmp,path,len);
|
||||
tmp[len] = 0;
|
||||
} else {
|
||||
strcpy(tmp,path);
|
||||
}
|
||||
dir = FindDirInfo(tmp,expand);
|
||||
} else {
|
||||
dir = FindDirInfo(path,expand);
|
||||
}
|
||||
|
||||
// LOG_DEBUG("DIR: Caching out %s : dir %s",expand,dir->orgname);
|
||||
// delete file objects...
|
||||
for(Bit32u i=0; i<dir->fileList.size(); i++) delete dir->fileList[i];
|
||||
// clear lists
|
||||
dir->fileList.clear();
|
||||
dir->longNameList.clear();
|
||||
dir->outputList.clear();
|
||||
dir->shortNr = 0;
|
||||
save_dir = 0;
|
||||
};
|
||||
|
||||
bool DOS_Drive_Cache::IsCachedIn(CFileInfo* curDir)
|
||||
{
|
||||
return (curDir->fileList.size()>0);
|
||||
};
|
||||
|
||||
|
||||
bool DOS_Drive_Cache::GetShortName(const char* fullname, char* shortname)
|
||||
{
|
||||
// Get Dir Info
|
||||
char expand[CROSS_LEN] = {0};
|
||||
CFileInfo* curDir = FindDirInfo(fullname,expand);
|
||||
|
||||
Bit16s low = 0;
|
||||
Bit16s high = curDir->longNameList.size()-1;
|
||||
Bit16s mid, res;
|
||||
|
||||
while (low<=high) {
|
||||
mid = (low+high)/2;
|
||||
res = strcmp(fullname,curDir->longNameList[mid]->orgname);
|
||||
if (res>0) low = mid+1; else
|
||||
if (res<0) high = mid-1;
|
||||
else {
|
||||
strcpy(shortname,curDir->longNameList[mid]->shortname);
|
||||
return true;
|
||||
};
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
Bit16u DOS_Drive_Cache::CreateShortNameID(CFileInfo* curDir, const char* name)
|
||||
{
|
||||
Bit16s foundNr = 0;
|
||||
Bit16s low = 0;
|
||||
Bit16s high = curDir->longNameList.size()-1;
|
||||
Bit16s mid, res;
|
||||
|
||||
while (low<=high) {
|
||||
mid = (low+high)/2;
|
||||
res = strncmp(name,curDir->longNameList[mid]->shortname,curDir->longNameList[mid]->compareCount);
|
||||
if (res>0) low = mid+1; else
|
||||
if (res<0) high = mid-1;
|
||||
else {
|
||||
// any more same x chars in next entries ?
|
||||
do {
|
||||
foundNr = curDir->longNameList[mid]->shortNr;
|
||||
mid++;
|
||||
} while(mid<curDir->longNameList.size() && (strncmp(name,curDir->longNameList[mid]->shortname,curDir->longNameList[mid]->compareCount)==0));
|
||||
break;
|
||||
};
|
||||
}
|
||||
return foundNr+1;
|
||||
};
|
||||
|
||||
bool DOS_Drive_Cache::RemoveTrailingDot(char* shortname)
|
||||
// remove trailing '.' if no extension is available (Linux compatibility)
|
||||
{
|
||||
Bitu len = strlen(shortname);
|
||||
if (len && (shortname[len-1]=='.')) {
|
||||
if (len==1) return false;
|
||||
if ((len==2) && (shortname[0]=='.')) return false;
|
||||
shortname[len-1] = 0;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
Bit16s DOS_Drive_Cache::GetLongName(CFileInfo* curDir, char* shortName)
|
||||
{
|
||||
// Remove dot, if no extension...
|
||||
RemoveTrailingDot(shortName);
|
||||
// Search long name and return array number of element
|
||||
Bit16s low = 0;
|
||||
Bit16s high = curDir->fileList.size()-1;
|
||||
Bit16s mid,res;
|
||||
while (low<=high) {
|
||||
mid = (low+high)/2;
|
||||
res = strcmp(shortName,curDir->fileList[mid]->shortname);
|
||||
if (res>0) low = mid+1; else
|
||||
if (res<0) high = mid-1; else
|
||||
{ // Found
|
||||
strcpy(shortName,curDir->fileList[mid]->orgname);
|
||||
return mid;
|
||||
};
|
||||
}
|
||||
// not available
|
||||
return -1;
|
||||
};
|
||||
|
||||
bool DOS_Drive_Cache::RemoveSpaces(char* str)
|
||||
// Removes all spaces
|
||||
{
|
||||
char* curpos = str;
|
||||
char* chkpos = str;
|
||||
while (*chkpos!=0) {
|
||||
if (*chkpos==' ') chkpos++; else *curpos++ = *chkpos++;
|
||||
}
|
||||
*curpos = 0;
|
||||
return (curpos!=chkpos);
|
||||
};
|
||||
|
||||
void DOS_Drive_Cache::CreateShortName(CFileInfo* curDir, CFileInfo* info)
|
||||
{
|
||||
Bit16s len = 0;
|
||||
Bit16s lenExt = 0;
|
||||
bool createShort = false;
|
||||
|
||||
char tmpNameBuffer[CROSS_LEN];
|
||||
|
||||
char* tmpName = tmpNameBuffer;
|
||||
|
||||
// Remove Spaces
|
||||
strcpy(tmpName,info->orgname);
|
||||
upcase(tmpName);
|
||||
createShort = RemoveSpaces(tmpName);
|
||||
|
||||
// Get Length of filename
|
||||
char* pos = strchr(tmpName,'.');
|
||||
if (pos) {
|
||||
// Get Length of extension
|
||||
lenExt = strlen(pos)-1;
|
||||
// ignore preceding '.' if extension is longer than "3"
|
||||
if (lenExt>3) {
|
||||
while (*tmpName=='.') tmpName++;
|
||||
createShort = true;
|
||||
};
|
||||
pos = strchr(tmpName,'.');
|
||||
if (pos) len = (Bit16u)(pos - tmpName);
|
||||
else len = strlen(tmpName);
|
||||
|
||||
} else
|
||||
len = strlen(tmpName);
|
||||
|
||||
// Should shortname version be created ?
|
||||
createShort = createShort || (len>8);
|
||||
if (!createShort) {
|
||||
char buffer[CROSS_LEN];
|
||||
strcpy(buffer,tmpName);
|
||||
createShort = (GetLongName(curDir,buffer)>=0);
|
||||
}
|
||||
|
||||
if (createShort) {
|
||||
// Create number
|
||||
char buffer[8];
|
||||
info->shortNr = CreateShortNameID(curDir,tmpName);
|
||||
sprintf(buffer,"%d",info->shortNr);
|
||||
// Copy first letters
|
||||
Bit16u tocopy;
|
||||
if (len+strlen(buffer)+1>8) tocopy = 8 - strlen(buffer) - 1;
|
||||
else tocopy = len;
|
||||
strncpy(info->shortname,tmpName,tocopy);
|
||||
info->shortname[tocopy] = 0;
|
||||
// Copy number
|
||||
strcat(info->shortname,"~");
|
||||
strcat(info->shortname,buffer);
|
||||
// Create compare Count
|
||||
info->compareCount = tocopy;
|
||||
// Add (and cut) Extension, if available
|
||||
if (pos) {
|
||||
// Step to last extension...
|
||||
pos = strrchr(tmpName, '.');
|
||||
// add extension
|
||||
strncat(info->shortname,pos,4);
|
||||
info->shortname[DOS_NAMELENGTH] = 0;
|
||||
};
|
||||
// Put it in longname list...
|
||||
curDir->longNameList.push_back(info);
|
||||
std::sort(curDir->longNameList.begin(), curDir->longNameList.end(), SortByName);
|
||||
} else {
|
||||
strcpy(info->shortname,tmpName);
|
||||
}
|
||||
RemoveTrailingDot(info->shortname);
|
||||
};
|
||||
|
||||
DOS_Drive_Cache::CFileInfo* DOS_Drive_Cache::FindDirInfo(const char* path, char* expandedPath)
|
||||
{
|
||||
// statics
|
||||
static char split[2] = { CROSS_FILESPLIT,0 };
|
||||
|
||||
char dir [CROSS_LEN];
|
||||
char work [CROSS_LEN];
|
||||
char* start = (char*)path;
|
||||
char* pos;
|
||||
CFileInfo* curDir = dirBase;
|
||||
Bit16u id;
|
||||
|
||||
if (save_dir && (strcmp(path,save_path)==0)) {
|
||||
strcpy(expandedPath,save_expanded);
|
||||
return save_dir;
|
||||
};
|
||||
|
||||
// LOG_DEBUG("DIR: Find %s",path);
|
||||
|
||||
// Remove base dir path
|
||||
start += strlen(basePath);
|
||||
strcpy(expandedPath,basePath);
|
||||
|
||||
// hehe, baseDir should be cached in...
|
||||
if (!IsCachedIn(curDir)) {
|
||||
strcpy(work,basePath);
|
||||
if (OpenDir(curDir,work,id)) {
|
||||
char buffer[CROSS_LEN];
|
||||
char * result;
|
||||
strcpy(buffer,dirPath);
|
||||
ReadDir(id,result);
|
||||
strcpy(dirPath,buffer);
|
||||
free[id] = true;
|
||||
};
|
||||
};
|
||||
|
||||
do {
|
||||
// bool errorcheck = false;
|
||||
pos = strchr(start,CROSS_FILESPLIT);
|
||||
if (pos) { strncpy(dir,start,pos-start); dir[pos-start] = 0; /*errorcheck = true;*/ }
|
||||
else { strcpy(dir,start); };
|
||||
|
||||
// Path found
|
||||
Bit16s nextDir = GetLongName(curDir,dir);
|
||||
strcat(expandedPath,dir);
|
||||
|
||||
// Error check
|
||||
/* if ((errorcheck) && (nextDir<0)) {
|
||||
LOG_DEBUG("DIR: Error: %s not found.",expandedPath);
|
||||
};
|
||||
*/
|
||||
// Follow Directory
|
||||
if ((nextDir>=0) && curDir->fileList[nextDir]->isDir) {
|
||||
curDir = curDir->fileList[nextDir];
|
||||
strcpy (curDir->orgname,dir);
|
||||
strcpy (work,path);
|
||||
// Cut Directory, if its only part of whole path
|
||||
if (pos) work[(Bit32u)pos-(Bit32u)path] = 0;
|
||||
if (!IsCachedIn(curDir)) {
|
||||
if (OpenDir(curDir,work,id)) {
|
||||
char buffer[CROSS_LEN];
|
||||
char * result;
|
||||
strcpy(buffer,dirPath);
|
||||
ReadDir(id,result);
|
||||
strcpy(dirPath,buffer);
|
||||
free[id] = true;
|
||||
};
|
||||
}
|
||||
};
|
||||
if (pos) {
|
||||
strcat(expandedPath,split);
|
||||
start = pos+1;
|
||||
}
|
||||
} while (pos);
|
||||
|
||||
// Save last result for faster access next time
|
||||
strcpy(save_path,path);
|
||||
strcpy(save_expanded,expandedPath);
|
||||
save_dir = curDir;
|
||||
|
||||
return curDir;
|
||||
};
|
||||
|
||||
bool DOS_Drive_Cache::OpenDir(const char* path, Bit16u& id)
|
||||
{
|
||||
char expand[CROSS_LEN] = {0};
|
||||
CFileInfo* dir = FindDirInfo(path,expand);
|
||||
if (OpenDir(dir,expand,id)) {
|
||||
dirSearch[id]->nextEntry = 0;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
bool DOS_Drive_Cache::OpenDir(CFileInfo* dir, char* expand, Bit16u& id)
|
||||
{
|
||||
id = GetFreeID(dir);
|
||||
dirSearch[id] = dir;
|
||||
// Add "/"
|
||||
char end[2]={CROSS_FILESPLIT,0};
|
||||
if (expand[strlen(expand)-1]!=CROSS_FILESPLIT) strcat(expand,end);
|
||||
// open dir
|
||||
if (dirSearch[id]) {
|
||||
// open dir
|
||||
DIR* dirp = opendir(expand);
|
||||
if (dirp) {
|
||||
// Reset it..
|
||||
closedir(dirp);
|
||||
strcpy(dirPath,expand);
|
||||
free[id] = false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
return false;
|
||||
};
|
||||
|
||||
void DOS_Drive_Cache::CreateEntry(CFileInfo* dir, const char* name)
|
||||
{
|
||||
struct stat status;
|
||||
CFileInfo* info = new CFileInfo;
|
||||
strcpy(info->orgname ,name);
|
||||
info->shortNr = 0;
|
||||
// Read and copy file stats
|
||||
char buffer[CROSS_LEN];
|
||||
strcpy(buffer,dirPath);
|
||||
strcat(buffer,info->orgname);
|
||||
if (stat(buffer,&status)==0) info->isDir = (S_ISDIR(status.st_mode)>0);
|
||||
else info->isDir = false;
|
||||
// Check for long filenames...
|
||||
CreateShortName(dir, info);
|
||||
// Put file in lists
|
||||
dir->fileList.push_back(info);
|
||||
dir->outputList.push_back(info);
|
||||
};
|
||||
|
||||
bool DOS_Drive_Cache::ReadDir(Bit16u id, char* &result)
|
||||
{
|
||||
// shouldnt happen...
|
||||
if (id>MAX_OPENDIRS) return false;
|
||||
|
||||
if (!IsCachedIn(dirSearch[id])) {
|
||||
// Try to open directory
|
||||
DIR* dirp = opendir(dirPath);
|
||||
if (!dirp) {
|
||||
free[id] = true;
|
||||
return false;
|
||||
}
|
||||
// Read complete directory
|
||||
struct dirent* tmpres;
|
||||
while ((tmpres = readdir(dirp))!=NULL) {
|
||||
CreateEntry(dirSearch[id],tmpres->d_name);
|
||||
// Sort Lists - filelist has to be alphabetically sorted, even in between (for finding double file names)
|
||||
// hmpf.. bit slow probably...
|
||||
std::sort(dirSearch[id]->fileList.begin(), dirSearch[id]->fileList.end(), SortByName);
|
||||
}
|
||||
// close dir
|
||||
closedir(dirp);
|
||||
// Output list - user defined
|
||||
switch (sortDirType) {
|
||||
case ALPHABETICAL : std::sort(dirSearch[id]->outputList.begin(), dirSearch[id]->outputList.end(), SortByName); break;
|
||||
case DIRALPHABETICAL : std::sort(dirSearch[id]->outputList.begin(), dirSearch[id]->outputList.end(), SortByDirName); break;
|
||||
case ALPHABETICALREV : std::sort(dirSearch[id]->outputList.begin(), dirSearch[id]->outputList.end(), SortByNameRev); break;
|
||||
case DIRALPHABETICALREV : std::sort(dirSearch[id]->outputList.begin(), dirSearch[id]->outputList.end(), SortByDirNameRev); break;
|
||||
case NOSORT : break;
|
||||
};
|
||||
// Info
|
||||
/* if (!dirp) {
|
||||
LOG_DEBUG("DIR: Error Caching in %s",dirPath);
|
||||
return false;
|
||||
} else {
|
||||
char buffer[128];
|
||||
sprintf(buffer,"DIR: Caching in %s (%d Files)",dirPath,dirSearch[srchNr]->fileList.size());
|
||||
LOG_DEBUG(buffer);
|
||||
};*/
|
||||
};
|
||||
if (SetResult(dirSearch[id], result, dirSearch[id]->nextEntry)) return true;
|
||||
free[id] = true;
|
||||
return false;
|
||||
};
|
||||
|
||||
bool DOS_Drive_Cache::SetResult(CFileInfo* dir, char* &result, Bit16u entryNr)
|
||||
{
|
||||
static char res[CROSS_LEN];
|
||||
|
||||
result = res;
|
||||
if (entryNr>=dir->outputList.size()) return false;
|
||||
CFileInfo* info = dir->outputList[entryNr];
|
||||
// copy filename, short version
|
||||
strcpy(res,info->shortname);
|
||||
// Set to next Entry
|
||||
dir->nextEntry = entryNr+1;
|
||||
return true;
|
||||
};
|
||||
|
||||
// ****************************************************************************
|
||||
// No Dir Cache,
|
||||
// ****************************************************************************
|
||||
|
||||
static DIR* srch_opendir = 0;
|
||||
|
||||
DOS_No_Drive_Cache::DOS_No_Drive_Cache(const char* path)
|
||||
{
|
||||
SetBaseDir(path);
|
||||
};
|
||||
|
||||
void DOS_No_Drive_Cache::SetBaseDir(const char* path)
|
||||
{
|
||||
strcpy(basePath,path);
|
||||
}
|
||||
|
||||
bool DOS_No_Drive_Cache::OpenDir(const char* path, Bit16u& id)
|
||||
{
|
||||
id = 0;
|
||||
strcpy(dirPath,path);
|
||||
if((srch_opendir=opendir(dirPath))==NULL) return false;
|
||||
return true;
|
||||
};
|
||||
|
||||
bool DOS_No_Drive_Cache::ReadDir(Bit16u id, char* &result)
|
||||
{
|
||||
|
||||
static char res[CROSS_LEN];
|
||||
dirent * ent;
|
||||
|
||||
if (!srch_opendir) return false;
|
||||
if ((ent=readdir(srch_opendir))==NULL) {
|
||||
strcpy(res,ent->d_name);
|
||||
result=res;
|
||||
closedir(srch_opendir);
|
||||
srch_opendir=NULL;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
@ -21,6 +21,7 @@
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <dirent.h>
|
||||
#include "dosbox.h"
|
||||
#include "dos_inc.h"
|
||||
#include "drives.h"
|
||||
@ -30,7 +31,7 @@
|
||||
|
||||
class localFile : public DOS_File {
|
||||
public:
|
||||
localFile(FILE * handle,Bit16u devinfo);
|
||||
localFile(const char* name, FILE * handle,Bit16u devinfo);
|
||||
bool Read(Bit8u * data,Bit16u * size);
|
||||
bool Write(Bit8u * data,Bit16u * size);
|
||||
bool Seek(Bit32u * pos,Bit32u type);
|
||||
@ -49,19 +50,20 @@ bool localDrive::FileCreate(DOS_File * * file,char * name,Bit16u attributes) {
|
||||
strcpy(newname,basedir);
|
||||
strcat(newname,name);
|
||||
CROSS_FILENAME(newname);
|
||||
FILE * hand=fopen(newname,"wb+");
|
||||
FILE * hand=fopen(dirCache.GetExpandName(newname),"wb+");
|
||||
if (!hand) return false;
|
||||
dirCache.AddEntry(newname, true);
|
||||
/* Make the 16 bit device information */
|
||||
*file=new localFile(hand,0x202);
|
||||
*file=new localFile(name,hand,0x202);
|
||||
return true;
|
||||
};
|
||||
|
||||
bool localDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) {
|
||||
char * type;
|
||||
switch (flags) {
|
||||
case OPEN_READ:type="rb";break;
|
||||
case OPEN_WRITE:type="rb+";break;
|
||||
case OPEN_READWRITE:type="rb+";break;
|
||||
case OPEN_READ:type="rb"; break;
|
||||
case OPEN_WRITE:type="rb+"; break;
|
||||
case OPEN_READWRITE:type="rb+"; break;
|
||||
default:
|
||||
//TODO FIX IT
|
||||
type="rb+";
|
||||
@ -72,10 +74,13 @@ bool localDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) {
|
||||
strcpy(newname,basedir);
|
||||
strcat(newname,name);
|
||||
CROSS_FILENAME(newname);
|
||||
dirCache.ExpandName(newname);
|
||||
|
||||
FILE * hand=fopen(newname,type);
|
||||
Bit32u err=errno;
|
||||
// Bit32u err=errno;
|
||||
if (!hand) return false;
|
||||
*file=new localFile(hand,0x202);
|
||||
*file=new localFile(name,hand,0x202);
|
||||
// (*file)->SetFileName(newname);
|
||||
return true;
|
||||
};
|
||||
|
||||
@ -84,54 +89,73 @@ bool localDrive::FileUnlink(char * name) {
|
||||
strcpy(newname,basedir);
|
||||
strcat(newname,name);
|
||||
CROSS_FILENAME(newname);
|
||||
if (!unlink(newname)) return true;
|
||||
if (!unlink(dirCache.GetExpandName(newname))) {
|
||||
dirCache.DeleteEntry(newname);
|
||||
return true;
|
||||
};
|
||||
return false;
|
||||
};
|
||||
|
||||
|
||||
bool localDrive::FindFirst(char * _dir,DOS_DTA & dta) {
|
||||
if (srch_opendir) closedir(srch_opendir);
|
||||
strcpy(srch_dir,basedir);
|
||||
strcat(srch_dir,_dir);
|
||||
CROSS_FILENAME(srch_dir);
|
||||
|
||||
char tempDir[CROSS_LEN];
|
||||
strcpy(tempDir,basedir);
|
||||
strcat(tempDir,_dir);
|
||||
CROSS_FILENAME(tempDir);
|
||||
|
||||
char end[2]={CROSS_FILESPLIT,0};
|
||||
if (srch_dir[strlen(srch_dir)-1]!=CROSS_FILESPLIT) strcat(srch_dir,end);
|
||||
if((srch_opendir=opendir(srch_dir))==NULL) return false;
|
||||
if (tempDir[strlen(tempDir)-1]!=CROSS_FILESPLIT) strcat(tempDir,end);
|
||||
|
||||
Bit16u id;
|
||||
if (!dirCache.OpenDir(tempDir,id)) return false;
|
||||
strcpy(srchInfo[id].srch_dir,tempDir);
|
||||
dta.SetDirID(id);
|
||||
return FindNext(dta);
|
||||
}
|
||||
|
||||
bool localDrive::FindNext(DOS_DTA & dta) {
|
||||
struct dirent * dir_ent;
|
||||
|
||||
char * dir_ent;
|
||||
struct stat stat_block;
|
||||
char full_name[CROSS_LEN];
|
||||
|
||||
Bit8u srch_attr;char srch_pattern[DOS_NAMELENGTH_ASCII];
|
||||
Bit8u find_attr;
|
||||
|
||||
if(!srch_opendir) return false;
|
||||
|
||||
dta.GetSearchParams(srch_attr,srch_pattern);
|
||||
again:
|
||||
if((dir_ent=readdir(srch_opendir))==NULL) {
|
||||
closedir(srch_opendir);
|
||||
srch_opendir=NULL;
|
||||
|
||||
Bit16u id = dta.GetDirID();
|
||||
|
||||
again:
|
||||
if (!dirCache.ReadDir(id,dir_ent)) {
|
||||
return false;
|
||||
}
|
||||
if(!WildFileCmp(dir_ent->d_name,srch_pattern)) goto again;
|
||||
strcpy(full_name,srch_dir);
|
||||
strcat(full_name,dir_ent->d_name);
|
||||
if(stat(full_name,&stat_block)!=0){
|
||||
|
||||
if(!WildFileCmp(dir_ent,srch_pattern)) goto again;
|
||||
|
||||
strcpy(full_name,srchInfo[id].srch_dir);
|
||||
strcat(full_name,dir_ent);
|
||||
if (stat(dirCache.GetExpandName(full_name),&stat_block)!=0) {
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
|
||||
if(S_ISDIR(stat_block.st_mode)) find_attr=DOS_ATTR_DIRECTORY;
|
||||
else find_attr=DOS_ATTR_ARCHIVE;
|
||||
if (~srch_attr & find_attr & (DOS_ATTR_DIRECTORY | DOS_ATTR_HIDDEN | DOS_ATTR_SYSTEM)) goto again;
|
||||
|
||||
if(S_ISDIR(stat_block.st_mode)) find_attr=DOS_ATTR_DIRECTORY;
|
||||
else find_attr=DOS_ATTR_ARCHIVE;
|
||||
if (~srch_attr & find_attr & (DOS_ATTR_DIRECTORY | DOS_ATTR_HIDDEN | DOS_ATTR_SYSTEM)) goto again;
|
||||
|
||||
/*file is okay, setup everything to be copied in DTA Block */
|
||||
char find_name[DOS_NAMELENGTH_ASCII];Bit16u find_date,find_time;Bit32u find_size;
|
||||
if(strlen(dir_ent->d_name)<DOS_NAMELENGTH_ASCII){
|
||||
strcpy(find_name,dir_ent->d_name);
|
||||
|
||||
if(strlen(dir_ent)<DOS_NAMELENGTH_ASCII){
|
||||
strcpy(find_name,dir_ent);
|
||||
upcase(find_name);
|
||||
} else strcpy(find_name,"LONGNAME.ERR");
|
||||
}
|
||||
|
||||
find_size=(Bit32u) stat_block.st_size;
|
||||
struct tm *time;
|
||||
if((time=localtime(&stat_block.st_mtime))!=0){
|
||||
@ -150,9 +174,10 @@ bool localDrive::GetFileAttr(char * name,Bit16u * attr) {
|
||||
strcpy(newname,basedir);
|
||||
strcat(newname,name);
|
||||
CROSS_FILENAME(newname);
|
||||
FILE * hand=fopen(newname,"rb");
|
||||
if (hand) {
|
||||
fclose(hand);
|
||||
dirCache.ExpandName(newname);
|
||||
|
||||
struct stat status;
|
||||
if (stat(newname,&status)==0) {
|
||||
*attr=DOS_ATTR_ARCHIVE;
|
||||
return true;
|
||||
}
|
||||
@ -166,10 +191,11 @@ bool localDrive::MakeDir(char * dir) {
|
||||
strcat(newdir,dir);
|
||||
CROSS_FILENAME(newdir);
|
||||
#if defined (WIN32) /* MS Visual C++ */
|
||||
int temp=mkdir(newdir);
|
||||
int temp=mkdir(dirCache.GetExpandName(newdir));
|
||||
#else
|
||||
int temp=mkdir(newdir,0700);
|
||||
int temp=mkdir(dirCache.GetExpandName(newdir),0700);
|
||||
#endif
|
||||
if (temp==0) dirCache.CacheOut(newdir,true);
|
||||
// if dir already exists, return success too.
|
||||
return (temp==0) || ((temp!=0) && (errno==EEXIST));
|
||||
}
|
||||
@ -179,7 +205,8 @@ bool localDrive::RemoveDir(char * dir) {
|
||||
strcpy(newdir,basedir);
|
||||
strcat(newdir,dir);
|
||||
CROSS_FILENAME(newdir);
|
||||
int temp=rmdir(newdir);
|
||||
int temp=rmdir(dirCache.GetExpandName(newdir));
|
||||
if (temp==0) dirCache.DeleteEntry(newdir,true);
|
||||
return (temp==0);
|
||||
}
|
||||
|
||||
@ -188,6 +215,7 @@ bool localDrive::TestDir(char * dir) {
|
||||
strcpy(newdir,basedir);
|
||||
strcat(newdir,dir);
|
||||
CROSS_FILENAME(newdir);
|
||||
dirCache.ExpandName(newdir);
|
||||
// Skip directory test, if "\"
|
||||
Bit16u len = strlen(newdir);
|
||||
if ((len>0) && (newdir[len-1]!='\\')) {
|
||||
@ -205,11 +233,14 @@ bool localDrive::Rename(char * oldname,char * newname) {
|
||||
strcpy(newold,basedir);
|
||||
strcat(newold,oldname);
|
||||
CROSS_FILENAME(newold);
|
||||
dirCache.ExpandName(newold);
|
||||
|
||||
char newnew[CROSS_LEN];
|
||||
strcpy(newnew,basedir);
|
||||
strcat(newnew,newname);
|
||||
CROSS_FILENAME(newnew);
|
||||
int temp=rename(newold,newnew);
|
||||
int temp=rename(newold,dirCache.GetExpandName(newnew));
|
||||
if (temp==0) dirCache.CacheOut(newnew);
|
||||
return (temp==0);
|
||||
|
||||
};
|
||||
@ -229,6 +260,7 @@ bool localDrive::FileExists(const char* name) {
|
||||
strcpy(newname,basedir);
|
||||
strcat(newname,name);
|
||||
CROSS_FILENAME(newname);
|
||||
dirCache.ExpandName(newname);
|
||||
FILE* Temp=fopen(newname,"rb");
|
||||
if(Temp==NULL) return false;
|
||||
fclose(Temp);
|
||||
@ -240,13 +272,14 @@ bool localDrive::FileStat(const char* name, FileStat_Block * const stat_block) {
|
||||
strcpy(newname,basedir);
|
||||
strcat(newname,name);
|
||||
CROSS_FILENAME(newname);
|
||||
dirCache.ExpandName(newname);
|
||||
struct stat temp_stat;
|
||||
if(stat(newname,&temp_stat)!=0) return false;
|
||||
/* Convert the stat to a FileStat */
|
||||
struct tm *time;
|
||||
if((time=localtime(&temp_stat.st_mtime))!=0) {
|
||||
stat_block->time=DOS_PackTime(time->tm_hour,time->tm_min,time->tm_sec);
|
||||
stat_block->date=DOS_PackDate(time->tm_year,time->tm_mon,time->tm_mday);
|
||||
stat_block->date=DOS_PackDate(time->tm_year+1900,time->tm_mon+1,time->tm_mday);
|
||||
} else {
|
||||
|
||||
}
|
||||
@ -262,12 +295,13 @@ Bit8u localDrive::GetMediaByte(void) {
|
||||
localDrive::localDrive(const char * startdir,Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid) {
|
||||
strcpy(basedir,startdir);
|
||||
sprintf(info,"local directory %s",startdir);
|
||||
srch_opendir=NULL;
|
||||
allocation.bytes_sector=_bytes_sector;
|
||||
allocation.sectors_cluster=_sectors_cluster;
|
||||
allocation.total_clusters=_total_clusters;
|
||||
allocation.free_clusters=_free_clusters;
|
||||
allocation.mediaid=_mediaid;
|
||||
|
||||
dirCache.SetBaseDir(basedir);
|
||||
}
|
||||
|
||||
|
||||
@ -301,17 +335,26 @@ bool localFile::Seek(Bit32u * pos,Bit32u type) {
|
||||
//TODO Give some doserrorcode;
|
||||
return false;//ERROR
|
||||
}
|
||||
fpos_t temppos;
|
||||
int ret=fseek(fhandle,*pos,seektype);
|
||||
if (ret!=0) {
|
||||
// Out of file range, pretend everythings ok
|
||||
// and move file pointer top end of file... ?! (Black Thorne)
|
||||
fseek(fhandle,0,SEEK_END);
|
||||
};
|
||||
#if 0
|
||||
fpos_t temppos;
|
||||
fgetpos(fhandle,&temppos);
|
||||
//TODO Hope we don't encouter files with 64 bits size
|
||||
Bit32u * fake_pos=(Bit32u*)&temppos;
|
||||
*pos=*fake_pos;
|
||||
#endif
|
||||
*pos=(Bit32u)ftell(fhandle);
|
||||
last_action=NONE;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool localFile::Close() {
|
||||
|
||||
open=false;
|
||||
fclose(fhandle);
|
||||
return true;
|
||||
}
|
||||
@ -319,9 +362,9 @@ bool localFile::Close() {
|
||||
Bit16u localFile::GetInformation(void) {
|
||||
return info;
|
||||
}
|
||||
|
||||
|
||||
|
||||
localFile::localFile(FILE * handle,Bit16u devinfo) {
|
||||
localFile::localFile(const char* _name, FILE * handle,Bit16u devinfo) {
|
||||
fhandle=handle;
|
||||
info=devinfo;
|
||||
struct stat temp_stat;
|
||||
@ -329,13 +372,90 @@ localFile::localFile(FILE * handle,Bit16u devinfo) {
|
||||
struct tm * ltime;
|
||||
if((ltime=localtime(&temp_stat.st_mtime))!=0) {
|
||||
time=DOS_PackTime(ltime->tm_hour,ltime->tm_min,ltime->tm_sec);
|
||||
date=DOS_PackDate(ltime->tm_year,ltime->tm_mon,ltime->tm_mday);
|
||||
date=DOS_PackDate(ltime->tm_year+1900,ltime->tm_mon+1,ltime->tm_mday);
|
||||
} else {
|
||||
time=0;date=0;
|
||||
time=1;date=1;
|
||||
}
|
||||
size=(Bit32u)temp_stat.st_size;
|
||||
attr=DOS_ATTR_ARCHIVE;
|
||||
last_action=NONE;
|
||||
|
||||
open=true;
|
||||
name=0;
|
||||
SetName(_name);
|
||||
}
|
||||
|
||||
// ********************************************
|
||||
// CDROM DRIVE
|
||||
// ********************************************
|
||||
|
||||
int MSCDEX_AddDrive(char driveLetter, const char* physicalPath, Bit8u& subUnit);
|
||||
bool MSCDEX_HasMediaChanged(Bit8u subUnit);
|
||||
|
||||
cdromDrive::cdromDrive(const char driveLetter, const char * startdir,Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid, int& error)
|
||||
:localDrive(startdir,_bytes_sector,_sectors_cluster,_total_clusters,_free_clusters,_mediaid)
|
||||
{
|
||||
// Init mscdex
|
||||
error = MSCDEX_AddDrive(driveLetter,startdir,subUnit);
|
||||
strcpy(info,"CDRom.");
|
||||
};
|
||||
|
||||
bool cdromDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags)
|
||||
{
|
||||
if ((flags==OPEN_READWRITE) || (flags==OPEN_WRITE)) {
|
||||
DOS_SetError(DOSERR_ACCESS_DENIED);
|
||||
return false;
|
||||
}
|
||||
return localDrive::FileOpen(file,name,flags);
|
||||
};
|
||||
|
||||
bool cdromDrive::FileCreate(DOS_File * * file,char * name,Bit16u attributes)
|
||||
{
|
||||
DOS_SetError(DOSERR_ACCESS_DENIED);
|
||||
return false;
|
||||
};
|
||||
|
||||
bool cdromDrive::FileUnlink(char * name)
|
||||
{
|
||||
DOS_SetError(DOSERR_ACCESS_DENIED);
|
||||
return false;
|
||||
};
|
||||
|
||||
bool cdromDrive::RemoveDir(char * dir)
|
||||
{
|
||||
DOS_SetError(DOSERR_ACCESS_DENIED);
|
||||
return false;
|
||||
};
|
||||
|
||||
bool cdromDrive::MakeDir(char * dir)
|
||||
{
|
||||
DOS_SetError(DOSERR_ACCESS_DENIED);
|
||||
return false;
|
||||
};
|
||||
|
||||
bool cdromDrive::Rename(char * oldname,char * newname)
|
||||
{
|
||||
DOS_SetError(DOSERR_ACCESS_DENIED);
|
||||
return false;
|
||||
};
|
||||
|
||||
bool cdromDrive::GetFileAttr(char * name,Bit16u * attr)
|
||||
{
|
||||
bool result = localDrive::GetFileAttr(name,attr);
|
||||
if (result) *attr |= DOS_ATTR_READ_ONLY;
|
||||
return result;
|
||||
};
|
||||
|
||||
bool cdromDrive::FindFirst(char * _dir,DOS_DTA & dta)
|
||||
{
|
||||
// If media has changed, reInit drivecache.
|
||||
if (MSCDEX_HasMediaChanged(subUnit)) dirCache.EmptyCache();
|
||||
return localDrive::FindFirst(_dir,dta);
|
||||
};
|
||||
|
||||
void cdromDrive::SetDir(const char* path)
|
||||
{
|
||||
// If media has changed, reInit drivecache.
|
||||
if (MSCDEX_HasMediaChanged(subUnit)) dirCache.EmptyCache();
|
||||
localDrive::SetDir(path);
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2002 The DOSBox Team
|
||||
* Copyright (C) 2002-2003 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -30,6 +30,8 @@ struct VFILE_Block {
|
||||
const char * name;
|
||||
Bit8u * data;
|
||||
Bit32u size;
|
||||
Bit16u date;
|
||||
Bit16u time;
|
||||
VFILE_Block * next;
|
||||
};
|
||||
|
||||
@ -41,6 +43,8 @@ void VFILE_Register(const char * name,Bit8u * data,Bit32u size) {
|
||||
new_file->name=name;
|
||||
new_file->data=data;
|
||||
new_file->size=size;
|
||||
new_file->date=DOS_PackDate(2002,10,1);
|
||||
new_file->time=DOS_PackTime(12,34,56);
|
||||
new_file->next=first_file;
|
||||
first_file=new_file;
|
||||
}
|
||||
@ -65,6 +69,8 @@ Virtual_File::Virtual_File(Bit8u * in_data,Bit32u in_size) {
|
||||
file_size=in_size;
|
||||
file_data=in_data;
|
||||
file_pos=0;
|
||||
date=DOS_PackDate(2002,10,1);
|
||||
time=DOS_PackTime(12,34,56);
|
||||
}
|
||||
|
||||
bool Virtual_File::Read(Bit8u * data,Bit16u * size) {
|
||||
@ -159,8 +165,8 @@ bool Virtual_Drive::FileStat(const char* name, FileStat_Block * const stat_block
|
||||
if (strcasecmp(name,cur_file->name)==0) {
|
||||
stat_block->attr=DOS_ATTR_ARCHIVE;
|
||||
stat_block->size=cur_file->size;
|
||||
stat_block->date=DOS_PackDate(2002,0,0);
|
||||
stat_block->time=DOS_PackTime(12,12,12);
|
||||
stat_block->date=DOS_PackDate(2002,10,1);
|
||||
stat_block->time=DOS_PackTime(12,34,56);
|
||||
return true;
|
||||
}
|
||||
cur_file=cur_file->next;
|
||||
@ -187,7 +193,7 @@ bool Virtual_Drive::FindNext(DOS_DTA & dta) {
|
||||
dta.GetSearchParams(attr,pattern);
|
||||
while (search_file) {
|
||||
if (WildFileCmp(search_file->name,pattern)) {
|
||||
dta.SetResult(search_file->name,search_file->size,6,2,DOS_ATTR_ARCHIVE);
|
||||
dta.SetResult(search_file->name,search_file->size,search_file->date,search_file->time,DOS_ATTR_ARCHIVE);
|
||||
search_file=search_file->next;
|
||||
return true;
|
||||
}
|
||||
|
@ -20,34 +20,35 @@
|
||||
#define _DRIVES_H__
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include "dos_system.h"
|
||||
#include "cross.h"
|
||||
|
||||
|
||||
bool WildFileCmp(const char * file, const char * wild);
|
||||
|
||||
class localDrive : public DOS_Drive {
|
||||
public:
|
||||
localDrive(const char * startdir,Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid);
|
||||
bool FileOpen(DOS_File * * file,char * name,Bit32u flags);
|
||||
bool FileCreate(DOS_File * * file,char * name,Bit16u attributes);
|
||||
bool FileUnlink(char * name);
|
||||
bool RemoveDir(char * dir);
|
||||
bool MakeDir(char * dir);
|
||||
bool TestDir(char * dir);
|
||||
bool FindFirst(char * _dir,DOS_DTA & dta);
|
||||
bool FindNext(DOS_DTA & dta);
|
||||
bool GetFileAttr(char * name,Bit16u * attr);
|
||||
bool Rename(char * oldname,char * newname);
|
||||
bool AllocationInfo(Bit16u * _bytes_sector,Bit8u * _sectors_cluster,Bit16u * _total_clusters,Bit16u * _free_clusters);
|
||||
bool FileExists(const char* name);
|
||||
bool FileStat(const char* name, FileStat_Block * const stat_block);
|
||||
Bit8u GetMediaByte(void);
|
||||
virtual bool FileOpen(DOS_File * * file,char * name,Bit32u flags);
|
||||
virtual bool FileCreate(DOS_File * * file,char * name,Bit16u attributes);
|
||||
virtual bool FileUnlink(char * name);
|
||||
virtual bool RemoveDir(char * dir);
|
||||
virtual bool MakeDir(char * dir);
|
||||
virtual bool TestDir(char * dir);
|
||||
virtual bool FindFirst(char * _dir,DOS_DTA & dta);
|
||||
virtual bool FindNext(DOS_DTA & dta);
|
||||
virtual bool GetFileAttr(char * name,Bit16u * attr);
|
||||
virtual bool Rename(char * oldname,char * newname);
|
||||
virtual bool AllocationInfo(Bit16u * _bytes_sector,Bit8u * _sectors_cluster,Bit16u * _total_clusters,Bit16u * _free_clusters);
|
||||
virtual bool FileExists(const char* name);
|
||||
virtual bool FileStat(const char* name, FileStat_Block * const stat_block);
|
||||
virtual Bit8u GetMediaByte(void);
|
||||
|
||||
private:
|
||||
char basedir[CROSS_LEN];
|
||||
char srch_dir[CROSS_LEN];
|
||||
DIR * srch_opendir;
|
||||
|
||||
struct {
|
||||
char srch_dir[CROSS_LEN];
|
||||
} srchInfo[MAX_OPENDIRS];
|
||||
|
||||
struct {
|
||||
Bit16u bytes_sector;
|
||||
Bit8u sectors_cluster;
|
||||
@ -57,8 +58,24 @@ private:
|
||||
} allocation;
|
||||
};
|
||||
|
||||
struct VFILE_Block;
|
||||
class cdromDrive : public localDrive
|
||||
{
|
||||
public:
|
||||
cdromDrive(const char driveLetter, const char * startdir,Bit16u _bytes_sector,Bit8u _sectors_cluster,Bit16u _total_clusters,Bit16u _free_clusters,Bit8u _mediaid, int& error);
|
||||
virtual bool FileOpen(DOS_File * * file,char * name,Bit32u flags);
|
||||
virtual bool FileCreate(DOS_File * * file,char * name,Bit16u attributes);
|
||||
virtual bool FileUnlink(char * name);
|
||||
virtual bool RemoveDir(char * dir);
|
||||
virtual bool MakeDir(char * dir);
|
||||
virtual bool Rename(char * oldname,char * newname);
|
||||
virtual bool GetFileAttr(char * name,Bit16u * attr);
|
||||
virtual bool FindFirst(char * _dir,DOS_DTA & dta);
|
||||
virtual void SetDir(const char* path);
|
||||
private:
|
||||
Bit8u subUnit;
|
||||
};
|
||||
|
||||
struct VFILE_Block;
|
||||
|
||||
class Virtual_Drive: public DOS_Drive {
|
||||
public:
|
||||
@ -81,4 +98,6 @@ private:
|
||||
VFILE_Block * search_file;
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
579
src/dos/scsidefs.h
Normal file
579
src/dos/scsidefs.h
Normal file
@ -0,0 +1,579 @@
|
||||
//***************************************************************************
|
||||
//
|
||||
// Name: SCSIDEFS.H
|
||||
//
|
||||
// Description: SCSI definitions ('C' Language)
|
||||
//
|
||||
//***************************************************************************
|
||||
|
||||
//***************************************************************************
|
||||
// %%% TARGET STATUS VALUES %%%
|
||||
//***************************************************************************
|
||||
#define STATUS_GOOD 0x00 // Status Good
|
||||
#define STATUS_CHKCOND 0x02 // Check Condition
|
||||
#define STATUS_CONDMET 0x04 // Condition Met
|
||||
#define STATUS_BUSY 0x08 // Busy
|
||||
#define STATUS_INTERM 0x10 // Intermediate
|
||||
#define STATUS_INTCDMET 0x14 // Intermediate-condition met
|
||||
#define STATUS_RESCONF 0x18 // Reservation conflict
|
||||
#define STATUS_COMTERM 0x22 // Command Terminated
|
||||
#define STATUS_QFULL 0x28 // Queue full
|
||||
|
||||
//***************************************************************************
|
||||
// %%% SCSI MISCELLANEOUS EQUATES %%%
|
||||
//***************************************************************************
|
||||
#define MAXLUN 7 // Maximum Logical Unit Id
|
||||
#define MAXTARG 7 // Maximum Target Id
|
||||
#define MAX_SCSI_LUNS 64 // Maximum Number of SCSI LUNs
|
||||
#define MAX_NUM_HA 8 // Maximum Number of SCSI HA's
|
||||
|
||||
//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
|
||||
//
|
||||
// %%% SCSI COMMAND OPCODES %%%
|
||||
//
|
||||
///\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
|
||||
|
||||
//***************************************************************************
|
||||
// %%% Commands for all Device Types %%%
|
||||
//***************************************************************************
|
||||
#define SCSI_CHANGE_DEF 0x40 // Change Definition (Optional)
|
||||
#define SCSI_COMPARE 0x39 // Compare (O)
|
||||
#define SCSI_COPY 0x18 // Copy (O)
|
||||
#define SCSI_COP_VERIFY 0x3A // Copy and Verify (O)
|
||||
#define SCSI_INQUIRY 0x12 // Inquiry (MANDATORY)
|
||||
#define SCSI_LOG_SELECT 0x4C // Log Select (O)
|
||||
#define SCSI_LOG_SENSE 0x4D // Log Sense (O)
|
||||
#define SCSI_MODE_SEL6 0x15 // Mode Select 6-byte (Device Specific)
|
||||
#define SCSI_MODE_SEL10 0x55 // Mode Select 10-byte (Device Specific)
|
||||
#define SCSI_MODE_SEN6 0x1A // Mode Sense 6-byte (Device Specific)
|
||||
#define SCSI_MODE_SEN10 0x5A // Mode Sense 10-byte (Device Specific)
|
||||
#define SCSI_READ_BUFF 0x3C // Read Buffer (O)
|
||||
#define SCSI_REQ_SENSE 0x03 // Request Sense (MANDATORY)
|
||||
#define SCSI_SEND_DIAG 0x1D // Send Diagnostic (O)
|
||||
#define SCSI_TST_U_RDY 0x00 // Test Unit Ready (MANDATORY)
|
||||
#define SCSI_WRITE_BUFF 0x3B // Write Buffer (O)
|
||||
|
||||
//***************************************************************************
|
||||
// %%% Commands Unique to Direct Access Devices %%%
|
||||
//***************************************************************************
|
||||
#define SCSI_COMPARE 0x39 // Compare (O)
|
||||
#define SCSI_FORMAT 0x04 // Format Unit (MANDATORY)
|
||||
#define SCSI_LCK_UN_CAC 0x36 // Lock Unlock Cache (O)
|
||||
#define SCSI_PREFETCH 0x34 // Prefetch (O)
|
||||
#define SCSI_MED_REMOVL 0x1E // Prevent/Allow medium Removal (O)
|
||||
#define SCSI_READ6 0x08 // Read 6-byte (MANDATORY)
|
||||
#define SCSI_READ10 0x28 // Read 10-byte (MANDATORY)
|
||||
#define SCSI_RD_CAPAC 0x25 // Read Capacity (MANDATORY)
|
||||
#define SCSI_RD_DEFECT 0x37 // Read Defect Data (O)
|
||||
#define SCSI_READ_LONG 0x3E // Read Long (O)
|
||||
#define SCSI_REASS_BLK 0x07 // Reassign Blocks (O)
|
||||
#define SCSI_RCV_DIAG 0x1C // Receive Diagnostic Results (O)
|
||||
#define SCSI_RELEASE 0x17 // Release Unit (MANDATORY)
|
||||
#define SCSI_REZERO 0x01 // Rezero Unit (O)
|
||||
#define SCSI_SRCH_DAT_E 0x31 // Search Data Equal (O)
|
||||
#define SCSI_SRCH_DAT_H 0x30 // Search Data High (O)
|
||||
#define SCSI_SRCH_DAT_L 0x32 // Search Data Low (O)
|
||||
#define SCSI_SEEK6 0x0B // Seek 6-Byte (O)
|
||||
#define SCSI_SEEK10 0x2B // Seek 10-Byte (O)
|
||||
#define SCSI_SEND_DIAG 0x1D // Send Diagnostics (MANDATORY)
|
||||
#define SCSI_SET_LIMIT 0x33 // Set Limits (O)
|
||||
#define SCSI_START_STP 0x1B // Start/Stop Unit (O)
|
||||
#define SCSI_SYNC_CACHE 0x35 // Synchronize Cache (O)
|
||||
#define SCSI_VERIFY 0x2F // Verify (O)
|
||||
#define SCSI_WRITE6 0x0A // Write 6-Byte (MANDATORY)
|
||||
#define SCSI_WRITE10 0x2A // Write 10-Byte (MANDATORY)
|
||||
#define SCSI_WRT_VERIFY 0x2E // Write and Verify (O)
|
||||
#define SCSI_WRITE_LONG 0x3F // Write Long (O)
|
||||
#define SCSI_WRITE_SAME 0x41 // Write Same (O)
|
||||
|
||||
//***************************************************************************
|
||||
// %%% Commands Unique to Sequential Access Devices %%%
|
||||
//***************************************************************************
|
||||
#define SCSI_ERASE 0x19 // Erase (MANDATORY)
|
||||
#define SCSI_LOAD_UN 0x1B // Load/Unload (O)
|
||||
#define SCSI_LOCATE 0x2B // Locate (O)
|
||||
#define SCSI_RD_BLK_LIM 0x05 // Read Block Limits (MANDATORY)
|
||||
#define SCSI_READ_POS 0x34 // Read Position (O)
|
||||
#define SCSI_READ_REV 0x0F // Read Reverse (O)
|
||||
#define SCSI_REC_BF_DAT 0x14 // Recover Buffer Data (O)
|
||||
#define SCSI_RESERVE 0x16 // Reserve Unit (MANDATORY)
|
||||
#define SCSI_REWIND 0x01 // Rewind (MANDATORY)
|
||||
#define SCSI_SPACE 0x11 // Space (MANDATORY)
|
||||
#define SCSI_VERIFY_T 0x13 // Verify (Tape) (O)
|
||||
#define SCSI_WRT_FILE 0x10 // Write Filemarks (MANDATORY)
|
||||
|
||||
//***************************************************************************
|
||||
// %%% Commands Unique to Printer Devices %%%
|
||||
//***************************************************************************
|
||||
#define SCSI_PRINT 0x0A // Print (MANDATORY)
|
||||
#define SCSI_SLEW_PNT 0x0B // Slew and Print (O)
|
||||
#define SCSI_STOP_PNT 0x1B // Stop Print (O)
|
||||
#define SCSI_SYNC_BUFF 0x10 // Synchronize Buffer (O)
|
||||
|
||||
//***************************************************************************
|
||||
// %%% Commands Unique to Processor Devices %%%
|
||||
//***************************************************************************
|
||||
#define SCSI_RECEIVE 0x08 // Receive (O)
|
||||
#define SCSI_SEND 0x0A // Send (O)
|
||||
|
||||
//***************************************************************************
|
||||
// %%% Commands Unique to Write-Once Devices %%%
|
||||
//***************************************************************************
|
||||
#define SCSI_MEDIUM_SCN 0x38 // Medium Scan (O)
|
||||
#define SCSI_SRCHDATE10 0x31 // Search Data Equal 10-Byte (O)
|
||||
#define SCSI_SRCHDATE12 0xB1 // Search Data Equal 12-Byte (O)
|
||||
#define SCSI_SRCHDATH10 0x30 // Search Data High 10-Byte (O)
|
||||
#define SCSI_SRCHDATH12 0xB0 // Search Data High 12-Byte (O)
|
||||
#define SCSI_SRCHDATL10 0x32 // Search Data Low 10-Byte (O)
|
||||
#define SCSI_SRCHDATL12 0xB2 // Search Data Low 12-Byte (O)
|
||||
#define SCSI_SET_LIM_10 0x33 // Set Limits 10-Byte (O)
|
||||
#define SCSI_SET_LIM_12 0xB3 // Set Limits 10-Byte (O)
|
||||
#define SCSI_VERIFY10 0x2F // Verify 10-Byte (O)
|
||||
#define SCSI_VERIFY12 0xAF // Verify 12-Byte (O)
|
||||
#define SCSI_WRITE12 0xAA // Write 12-Byte (O)
|
||||
#define SCSI_WRT_VER10 0x2E // Write and Verify 10-Byte (O)
|
||||
#define SCSI_WRT_VER12 0xAE // Write and Verify 12-Byte (O)
|
||||
|
||||
//***************************************************************************
|
||||
// %%% Commands Unique to CD-ROM Devices %%%
|
||||
//***************************************************************************
|
||||
#define SCSI_PLAYAUD_10 0x45 // Play Audio 10-Byte (O)
|
||||
#define SCSI_PLAYAUD_12 0xA5 // Play Audio 12-Byte 12-Byte (O)
|
||||
#define SCSI_PLAYAUDMSF 0x47 // Play Audio MSF (O)
|
||||
#define SCSI_PLAYA_TKIN 0x48 // Play Audio Track/Index (O)
|
||||
#define SCSI_PLYTKREL10 0x49 // Play Track Relative 10-Byte (O)
|
||||
#define SCSI_PLYTKREL12 0xA9 // Play Track Relative 12-Byte (O)
|
||||
#define SCSI_READCDCAP 0x25 // Read CD-ROM Capacity (MANDATORY)
|
||||
#define SCSI_READHEADER 0x44 // Read Header (O)
|
||||
#define SCSI_SUBCHANNEL 0x42 // Read Subchannel (O)
|
||||
#define SCSI_READ_TOC 0x43 // Read TOC (O)
|
||||
|
||||
//***************************************************************************
|
||||
// %%% Commands Unique to Scanner Devices %%%
|
||||
//***************************************************************************
|
||||
#define SCSI_GETDBSTAT 0x34 // Get Data Buffer Status (O)
|
||||
#define SCSI_GETWINDOW 0x25 // Get Window (O)
|
||||
#define SCSI_OBJECTPOS 0x31 // Object Postion (O)
|
||||
#define SCSI_SCAN 0x1B // Scan (O)
|
||||
#define SCSI_SETWINDOW 0x24 // Set Window (MANDATORY)
|
||||
|
||||
//***************************************************************************
|
||||
// %%% Commands Unique to Optical Memory Devices %%%
|
||||
//***************************************************************************
|
||||
#define SCSI_UpdateBlk 0x3D // Update Block (O)
|
||||
|
||||
//***************************************************************************
|
||||
// %%% Commands Unique to Medium Changer Devices %%%
|
||||
//***************************************************************************
|
||||
#define SCSI_EXCHMEDIUM 0xA6 // Exchange Medium (O)
|
||||
#define SCSI_INITELSTAT 0x07 // Initialize Element Status (O)
|
||||
#define SCSI_POSTOELEM 0x2B // Position to Element (O)
|
||||
#define SCSI_REQ_VE_ADD 0xB5 // Request Volume Element Address (O)
|
||||
#define SCSI_SENDVOLTAG 0xB6 // Send Volume Tag (O)
|
||||
|
||||
//***************************************************************************
|
||||
// %%% Commands Unique to Communication Devices %%%
|
||||
//***************************************************************************
|
||||
#define SCSI_GET_MSG_6 0x08 // Get Message 6-Byte (MANDATORY)
|
||||
#define SCSI_GET_MSG_10 0x28 // Get Message 10-Byte (O)
|
||||
#define SCSI_GET_MSG_12 0xA8 // Get Message 12-Byte (O)
|
||||
#define SCSI_SND_MSG_6 0x0A // Send Message 6-Byte (MANDATORY)
|
||||
#define SCSI_SND_MSG_10 0x2A // Send Message 10-Byte (O)
|
||||
#define SCSI_SND_MSG_12 0xAA // Send Message 12-Byte (O)
|
||||
|
||||
//\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
|
||||
//
|
||||
// %%% END OF SCSI COMMAND OPCODES %%%
|
||||
//
|
||||
///\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/
|
||||
|
||||
//***************************************************************************
|
||||
// %%% Request Sense Data Format %%%
|
||||
//***************************************************************************
|
||||
typedef struct {
|
||||
|
||||
BYTE ErrorCode; // Error Code (70H or 71H)
|
||||
BYTE SegmentNum; // Number of current segment descriptor
|
||||
BYTE SenseKey; // Sense Key(See bit definitions too)
|
||||
BYTE InfoByte0; // Information MSB
|
||||
BYTE InfoByte1; // Information MID
|
||||
BYTE InfoByte2; // Information MID
|
||||
BYTE InfoByte3; // Information LSB
|
||||
BYTE AddSenLen; // Additional Sense Length
|
||||
BYTE ComSpecInf0; // Command Specific Information MSB
|
||||
BYTE ComSpecInf1; // Command Specific Information MID
|
||||
BYTE ComSpecInf2; // Command Specific Information MID
|
||||
BYTE ComSpecInf3; // Command Specific Information LSB
|
||||
BYTE AddSenseCode; // Additional Sense Code
|
||||
BYTE AddSenQual; // Additional Sense Code Qualifier
|
||||
BYTE FieldRepUCode; // Field Replaceable Unit Code
|
||||
BYTE SenKeySpec15; // Sense Key Specific 15th byte
|
||||
BYTE SenKeySpec16; // Sense Key Specific 16th byte
|
||||
BYTE SenKeySpec17; // Sense Key Specific 17th byte
|
||||
BYTE AddSenseBytes; // Additional Sense Bytes
|
||||
|
||||
} SENSE_DATA_FMT;
|
||||
|
||||
//***************************************************************************
|
||||
// %%% REQUEST SENSE ERROR CODE %%%
|
||||
//***************************************************************************
|
||||
#define SERROR_CURRENT 0x70 // Current Errors
|
||||
#define SERROR_DEFERED 0x71 // Deferred Errors
|
||||
|
||||
//***************************************************************************
|
||||
// %%% REQUEST SENSE BIT DEFINITIONS %%%
|
||||
//***************************************************************************
|
||||
#define SENSE_VALID 0x80 // Byte 0 Bit 7
|
||||
#define SENSE_FILEMRK 0x80 // Byte 2 Bit 7
|
||||
#define SENSE_EOM 0x40 // Byte 2 Bit 6
|
||||
#define SENSE_ILI 0x20 // Byte 2 Bit 5
|
||||
|
||||
//***************************************************************************
|
||||
// %%% REQUEST SENSE SENSE KEY DEFINITIONS %%%
|
||||
//***************************************************************************
|
||||
#define KEY_NOSENSE 0x00 // No Sense
|
||||
#define KEY_RECERROR 0x01 // Recovered Error
|
||||
#define KEY_NOTREADY 0x02 // Not Ready
|
||||
#define KEY_MEDIUMERR 0x03 // Medium Error
|
||||
#define KEY_HARDERROR 0x04 // Hardware Error
|
||||
#define KEY_ILLGLREQ 0x05 // Illegal Request
|
||||
#define KEY_UNITATT 0x06 // Unit Attention
|
||||
#define KEY_DATAPROT 0x07 // Data Protect
|
||||
#define KEY_BLANKCHK 0x08 // Blank Check
|
||||
#define KEY_VENDSPEC 0x09 // Vendor Specific
|
||||
#define KEY_COPYABORT 0x0A // Copy Abort
|
||||
#define KEY_EQUAL 0x0C // Equal (Search)
|
||||
#define KEY_VOLOVRFLW 0x0D // Volume Overflow
|
||||
#define KEY_MISCOMP 0x0E // Miscompare (Search)
|
||||
#define KEY_RESERVED 0x0F // Reserved
|
||||
|
||||
//***************************************************************************
|
||||
// %%% PERIPHERAL DEVICE TYPE DEFINITIONS %%%
|
||||
//***************************************************************************
|
||||
#define DTYPE_DASD 0x00 // Disk Device
|
||||
#define DTYPE_SEQD 0x01 // Tape Device
|
||||
#define DTYPE_PRNT 0x02 // Printer
|
||||
#define DTYPE_PROC 0x03 // Processor
|
||||
#define DTYPE_WORM 0x04 // Write-once read-multiple
|
||||
#define DTYPE_CROM 0x05 // CD-ROM device
|
||||
#define DTYPE_CDROM 0x05 // CD-ROM device
|
||||
#define DTYPE_SCAN 0x06 // Scanner device
|
||||
#define DTYPE_OPTI 0x07 // Optical memory device
|
||||
#define DTYPE_JUKE 0x08 // Medium Changer device
|
||||
#define DTYPE_COMM 0x09 // Communications device
|
||||
#define DTYPE_RESL 0x0A // Reserved (low)
|
||||
#define DTYPE_RESH 0x1E // Reserved (high)
|
||||
#define DTYPE_UNKNOWN 0x1F // Unknown or no device type
|
||||
|
||||
//***************************************************************************
|
||||
// %%% ANSI APPROVED VERSION DEFINITIONS %%%
|
||||
//***************************************************************************
|
||||
#define ANSI_MAYBE 0x0 // Device may or may not be ANSI approved stand
|
||||
#define ANSI_SCSI1 0x1 // Device complies to ANSI X3.131-1986 (SCSI-1)
|
||||
#define ANSI_SCSI2 0x2 // Device complies to SCSI-2
|
||||
#define ANSI_RESLO 0x3 // Reserved (low)
|
||||
#define ANSI_RESHI 0x7 // Reserved (high)
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct {
|
||||
USHORT Length;
|
||||
UCHAR ScsiStatus;
|
||||
UCHAR PathId;
|
||||
UCHAR TargetId;
|
||||
UCHAR Lun;
|
||||
UCHAR CdbLength;
|
||||
UCHAR SenseInfoLength;
|
||||
UCHAR DataIn;
|
||||
ULONG DataTransferLength;
|
||||
ULONG TimeOutValue;
|
||||
ULONG DataBufferOffset;
|
||||
ULONG SenseInfoOffset;
|
||||
UCHAR Cdb[16];
|
||||
} SCSI_PASS_THROUGH, *PSCSI_PASS_THROUGH;
|
||||
|
||||
|
||||
typedef struct {
|
||||
USHORT Length;
|
||||
UCHAR ScsiStatus;
|
||||
UCHAR PathId;
|
||||
UCHAR TargetId;
|
||||
UCHAR Lun;
|
||||
UCHAR CdbLength;
|
||||
UCHAR SenseInfoLength;
|
||||
UCHAR DataIn;
|
||||
ULONG DataTransferLength;
|
||||
ULONG TimeOutValue;
|
||||
PVOID DataBuffer;
|
||||
ULONG SenseInfoOffset;
|
||||
UCHAR Cdb[16];
|
||||
} SCSI_PASS_THROUGH_DIRECT, *PSCSI_PASS_THROUGH_DIRECT;
|
||||
|
||||
|
||||
typedef struct {
|
||||
SCSI_PASS_THROUGH spt;
|
||||
ULONG Filler;
|
||||
UCHAR ucSenseBuf[32];
|
||||
UCHAR ucDataBuf[512];
|
||||
} SCSI_PASS_THROUGH_WITH_BUFFERS, *PSCSI_PASS_THROUGH_WITH_BUFFERS;
|
||||
|
||||
|
||||
typedef struct {
|
||||
SCSI_PASS_THROUGH_DIRECT spt;
|
||||
ULONG Filler;
|
||||
UCHAR ucSenseBuf[32];
|
||||
} SCSI_PASS_THROUGH_DIRECT_WITH_BUFFER, *PSCSI_PASS_THROUGH_DIRECT_WITH_BUFFER;
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
UCHAR NumberOfLogicalUnits;
|
||||
UCHAR InitiatorBusId;
|
||||
ULONG InquiryDataOffset;
|
||||
} SCSI_BUS_DATA, *PSCSI_BUS_DATA;
|
||||
|
||||
|
||||
typedef struct {
|
||||
UCHAR NumberOfBusses;
|
||||
SCSI_BUS_DATA BusData[1];
|
||||
} SCSI_ADAPTER_BUS_INFO, *PSCSI_ADAPTER_BUS_INFO;
|
||||
|
||||
|
||||
typedef struct {
|
||||
UCHAR PathId;
|
||||
UCHAR TargetId;
|
||||
UCHAR Lun;
|
||||
BOOLEAN DeviceClaimed;
|
||||
ULONG InquiryDataLength;
|
||||
ULONG NextInquiryDataOffset;
|
||||
UCHAR InquiryData[1];
|
||||
} SCSI_INQUIRY_DATA, *PSCSI_INQUIRY_DATA;
|
||||
|
||||
|
||||
typedef struct {
|
||||
ULONG Length;
|
||||
UCHAR PortNumber;
|
||||
UCHAR PathId;
|
||||
UCHAR TargetId;
|
||||
UCHAR Lun;
|
||||
} SCSI_ADDRESS, *PSCSI_ADDRESS;
|
||||
|
||||
|
||||
/*
|
||||
* method codes
|
||||
*/
|
||||
#define METHOD_BUFFERED 0
|
||||
#define METHOD_IN_DIRECT 1
|
||||
#define METHOD_OUT_DIRECT 2
|
||||
#define METHOD_NEITHER 3
|
||||
|
||||
/*
|
||||
* file access values
|
||||
*/
|
||||
#define FILE_ANY_ACCESS 0
|
||||
#define FILE_READ_ACCESS (0x0001)
|
||||
#define FILE_WRITE_ACCESS (0x0002)
|
||||
|
||||
|
||||
#define IOCTL_SCSI_BASE 0x00000004
|
||||
|
||||
/*
|
||||
* constants for DataIn member of SCSI_PASS_THROUGH* structures
|
||||
*/
|
||||
#define SCSI_IOCTL_DATA_OUT 0
|
||||
#define SCSI_IOCTL_DATA_IN 1
|
||||
#define SCSI_IOCTL_DATA_UNSPECIFIED 2
|
||||
|
||||
/*
|
||||
* Standard IOCTL define
|
||||
*/
|
||||
#define CTL_CODE( DevType, Function, Method, Access ) ( \
|
||||
((DevType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
|
||||
)
|
||||
|
||||
#define IOCTL_SCSI_PASS_THROUGH CTL_CODE( IOCTL_SCSI_BASE, 0x0401, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS )
|
||||
#define IOCTL_SCSI_MINIPORT CTL_CODE( IOCTL_SCSI_BASE, 0x0402, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS )
|
||||
#define IOCTL_SCSI_GET_INQUIRY_DATA CTL_CODE( IOCTL_SCSI_BASE, 0x0403, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_SCSI_GET_CAPABILITIES CTL_CODE( IOCTL_SCSI_BASE, 0x0404, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_SCSI_PASS_THROUGH_DIRECT CTL_CODE( IOCTL_SCSI_BASE, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS )
|
||||
#define IOCTL_SCSI_GET_ADDRESS CTL_CODE( IOCTL_SCSI_BASE, 0x0406, METHOD_BUFFERED, FILE_ANY_ACCESS )
|
||||
|
||||
#define FILE_DEVICE_MASS_STORAGE 0x0000002d
|
||||
#define IOCTL_STORAGE_BASE FILE_DEVICE_MASS_STORAGE
|
||||
|
||||
#define IOCTL_STORAGE_CHECK_VERIFY CTL_CODE(IOCTL_STORAGE_BASE, 0x0200, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_STORAGE_CHECK_VERIFY2 CTL_CODE(IOCTL_STORAGE_BASE, 0x0200, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_STORAGE_MEDIA_REMOVAL CTL_CODE(IOCTL_STORAGE_BASE, 0x0201, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_STORAGE_EJECT_MEDIA CTL_CODE(IOCTL_STORAGE_BASE, 0x0202, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_STORAGE_LOAD_MEDIA CTL_CODE(IOCTL_STORAGE_BASE, 0x0203, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_STORAGE_LOAD_MEDIA2 CTL_CODE(IOCTL_STORAGE_BASE, 0x0203, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
||||
#define IOCTL_STORAGE_RESERVE CTL_CODE(IOCTL_STORAGE_BASE, 0x0204, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_STORAGE_RELEASE CTL_CODE(IOCTL_STORAGE_BASE, 0x0205, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_STORAGE_FIND_NEW_DEVICES CTL_CODE(IOCTL_STORAGE_BASE, 0x0206, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
|
||||
#define FILE_DEVICE_CD_ROM 0x00000002
|
||||
#define IOCTL_CDROM_BASE FILE_DEVICE_CD_ROM
|
||||
#define IOCTL_CDROM_RAW_READ CTL_CODE(IOCTL_CDROM_BASE, 0x000F, METHOD_OUT_DIRECT, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_READ_Q_CHANNEL CTL_CODE(IOCTL_CDROM_BASE, 0x000B, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_CDROM_SEEK_AUDIO_MSF CTL_CODE(IOCTL_CDROM_BASE, 0x0001, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
|
||||
typedef struct _CDROM_SEEK_AUDIO_MSF {
|
||||
UCHAR M;
|
||||
UCHAR S;
|
||||
UCHAR F;
|
||||
} CDROM_SEEK_AUDIO_MSF, *PCDROM_SEEK_AUDIO_MSF;
|
||||
|
||||
//
|
||||
// CD ROM Sub-Q Channel Data Format
|
||||
//
|
||||
|
||||
#define IOCTL_CDROM_SUB_Q_CHANNEL 0x00
|
||||
#define IOCTL_CDROM_CURRENT_POSITION 0x01
|
||||
#define IOCTL_CDROM_MEDIA_CATALOG 0x02
|
||||
#define IOCTL_CDROM_TRACK_ISRC 0x03
|
||||
|
||||
typedef struct _CDROM_SUB_Q_DATA_FORMAT {
|
||||
UCHAR Format;
|
||||
UCHAR Track;
|
||||
} CDROM_SUB_Q_DATA_FORMAT, *PCDROM_SUB_Q_DATA_FORMAT;
|
||||
|
||||
typedef struct _SUB_Q_HEADER {
|
||||
UCHAR Reserved;
|
||||
UCHAR AudioStatus;
|
||||
UCHAR DataLength[2];
|
||||
} SUB_Q_HEADER, *PSUB_Q_HEADER;
|
||||
|
||||
typedef struct _SUB_Q_CURRENT_POSITION {
|
||||
SUB_Q_HEADER Header;
|
||||
UCHAR FormatCode;
|
||||
UCHAR Control : 4;
|
||||
UCHAR ADR : 4;
|
||||
UCHAR TrackNumber;
|
||||
UCHAR IndexNumber;
|
||||
UCHAR AbsoluteAddress[4];
|
||||
UCHAR TrackRelativeAddress[4];
|
||||
} SUB_Q_CURRENT_POSITION, *PSUB_Q_CURRENT_POSITION;
|
||||
|
||||
typedef struct _SUB_Q_MEDIA_CATALOG_NUMBER {
|
||||
SUB_Q_HEADER Header;
|
||||
UCHAR FormatCode;
|
||||
UCHAR Reserved[3];
|
||||
UCHAR Reserved1 : 7;
|
||||
UCHAR Mcval : 1;
|
||||
UCHAR MediaCatalog[15];
|
||||
} SUB_Q_MEDIA_CATALOG_NUMBER, *PSUB_Q_MEDIA_CATALOG_NUMBER;
|
||||
|
||||
typedef struct _SUB_Q_TRACK_ISRC {
|
||||
SUB_Q_HEADER Header;
|
||||
UCHAR FormatCode;
|
||||
UCHAR Reserved0;
|
||||
UCHAR Track;
|
||||
UCHAR Reserved1;
|
||||
UCHAR Reserved2 : 7;
|
||||
UCHAR Tcval : 1;
|
||||
UCHAR TrackIsrc[15];
|
||||
} SUB_Q_TRACK_ISRC, *PSUB_Q_TRACK_ISRC;
|
||||
|
||||
typedef union _SUB_Q_CHANNEL_DATA {
|
||||
SUB_Q_CURRENT_POSITION CurrentPosition;
|
||||
SUB_Q_MEDIA_CATALOG_NUMBER MediaCatalog;
|
||||
SUB_Q_TRACK_ISRC TrackIsrc;
|
||||
} SUB_Q_CHANNEL_DATA, *PSUB_Q_CHANNEL_DATA;
|
||||
|
||||
|
||||
// IOCTL_DISK_SET_CACHE allows the caller to get or set the state of the disk
|
||||
// read/write caches.
|
||||
//
|
||||
// If the structure is provided as the input buffer for the ioctl the read &
|
||||
// write caches will be enabled or disabled depending on the parameters
|
||||
// provided.
|
||||
//
|
||||
// If the structure is provided as an output buffer for the ioctl the state
|
||||
// of the read & write caches will be returned. If both input and outut buffers
|
||||
// are provided the output buffer will contain the cache state BEFORE any
|
||||
// changes are made
|
||||
|
||||
|
||||
typedef enum {
|
||||
EqualPriority,
|
||||
KeepPrefetchedData,
|
||||
KeepReadData
|
||||
} DISK_CACHE_RETENTION_PRIORITY;
|
||||
|
||||
#define FILE_DEVICE_DISK 0x00000007
|
||||
#define IOCTL_DISK_BASE FILE_DEVICE_DISK
|
||||
#define IOCTL_DISK_GET_CACHE_INFORMATION CTL_CODE(IOCTL_DISK_BASE, 0x0035, METHOD_BUFFERED, FILE_READ_ACCESS)
|
||||
#define IOCTL_DISK_SET_CACHE_INFORMATION CTL_CODE(IOCTL_DISK_BASE, 0x0036, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
|
||||
|
||||
typedef struct _DISK_CACHE_INFORMATION {
|
||||
|
||||
//
|
||||
// on return indicates that the device is capable of saving any parameters
|
||||
// in non-volatile storage. On send indicates that the device should
|
||||
// save the state in non-volatile storage.
|
||||
//
|
||||
|
||||
BOOLEAN ParametersSavable;
|
||||
|
||||
//
|
||||
// Indicates whether the write and read caches are enabled.
|
||||
//
|
||||
|
||||
BOOLEAN ReadCacheEnabled;
|
||||
BOOLEAN WriteCacheEnabled;
|
||||
|
||||
//
|
||||
// Controls the likelyhood of data remaining in the cache depending on how
|
||||
// it got there. Data cached from a READ or WRITE operation may be given
|
||||
// higher, lower or equal priority to data entered into the cache for other
|
||||
// means (like prefetch)
|
||||
//
|
||||
|
||||
DISK_CACHE_RETENTION_PRIORITY ReadRetentionPriority;
|
||||
DISK_CACHE_RETENTION_PRIORITY WriteRetentionPriority;
|
||||
|
||||
//
|
||||
// Requests for a larger number of blocks than this may have prefetching
|
||||
// disabled. If this value is set to 0 prefetch will be disabled.
|
||||
//
|
||||
|
||||
USHORT DisablePrefetchTransferLength;
|
||||
|
||||
//
|
||||
// If TRUE then ScalarPrefetch (below) will be valid. If FALSE then
|
||||
// the minimum and maximum values should be treated as a block count
|
||||
// (BlockPrefetch)
|
||||
//
|
||||
|
||||
BOOLEAN PrefetchScalar;
|
||||
|
||||
//
|
||||
// Contains the minimum and maximum amount of data which will be
|
||||
// will be prefetched into the cache on a disk operation. This value
|
||||
// may either be a scalar multiplier of the transfer length of the request,
|
||||
// or an abolute number of disk blocks. PrefetchScalar (above) indicates
|
||||
// which interpretation is used.
|
||||
//
|
||||
|
||||
union {
|
||||
struct {
|
||||
USHORT Minimum;
|
||||
USHORT Maximum;
|
||||
|
||||
//
|
||||
// The maximum number of blocks which will be prefetched - useful
|
||||
// with the scalar limits to set definite upper limits.
|
||||
//
|
||||
|
||||
USHORT MaximumBlocks;
|
||||
} ScalarPrefetch;
|
||||
|
||||
struct {
|
||||
USHORT Minimum;
|
||||
USHORT Maximum;
|
||||
} BlockPrefetch;
|
||||
};
|
||||
|
||||
} DISK_CACHE_INFORMATION, *PDISK_CACHE_INFORMATION;
|
||||
|
354
src/dos/wnaspi32.h
Normal file
354
src/dos/wnaspi32.h
Normal file
@ -0,0 +1,354 @@
|
||||
/******************************************************************************
|
||||
**
|
||||
** Module Name: wnaspi32.h
|
||||
**
|
||||
** Description: Header file for ASPI for Win32. This header includes
|
||||
** macro and type declarations, and can be included without
|
||||
** modification when using Borland C++ or Microsoft Visual
|
||||
** C++ with 32-bit compilation. If you are using a different
|
||||
** compiler then you MUST ensure that structures are packed
|
||||
** onto byte alignments, and that C++ name mangling is turned
|
||||
** off.
|
||||
**
|
||||
** Notes: This file created using 4 spaces per tab.
|
||||
**
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __WNASPI32_H__
|
||||
#define __WNASPI32_H__
|
||||
|
||||
/*
|
||||
** Make sure structures are packed and undecorated.
|
||||
*/
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma option -a1
|
||||
#endif //__BORLANDC__
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack(1)
|
||||
#endif //__MSC_VER
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif //__cplusplus
|
||||
|
||||
//*****************************************************************************
|
||||
// %%% SCSI MISCELLANEOUS EQUATES %%%
|
||||
//*****************************************************************************
|
||||
|
||||
#define SENSE_LEN 14 // Default sense buffer length
|
||||
#define SRB_DIR_SCSI 0x00 // Direction determined by SCSI
|
||||
#define SRB_POSTING 0x01 // Enable ASPI posting
|
||||
#define SRB_ENABLE_RESIDUAL_COUNT 0x04 // Enable residual byte count reporting
|
||||
#define SRB_DIR_IN 0x08 // Transfer from SCSI target to host
|
||||
#define SRB_DIR_OUT 0x10 // Transfer from host to SCSI target
|
||||
#define SRB_EVENT_NOTIFY 0x40 // Enable ASPI event notification
|
||||
|
||||
#define RESIDUAL_COUNT_SUPPORTED 0x02 // Extended buffer flag
|
||||
#define MAX_SRB_TIMEOUT 108000lu // 30 hour maximum timeout in s
|
||||
#define DEFAULT_SRB_TIMEOUT 108000lu // Max timeout by default
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// %%% ASPI Command Definitions %%%
|
||||
//*****************************************************************************
|
||||
|
||||
#define SC_HA_INQUIRY 0x00 // Host adapter inquiry
|
||||
#define SC_GET_DEV_TYPE 0x01 // Get device type
|
||||
#define SC_EXEC_SCSI_CMD 0x02 // Execute SCSI command
|
||||
#define SC_ABORT_SRB 0x03 // Abort an SRB
|
||||
#define SC_RESET_DEV 0x04 // SCSI bus device reset
|
||||
#define SC_SET_HA_PARMS 0x05 // Set HA parameters
|
||||
#define SC_GET_DISK_INFO 0x06 // Get Disk information
|
||||
#define SC_RESCAN_SCSI_BUS 0x07 // ReBuild SCSI device map
|
||||
#define SC_GETSET_TIMEOUTS 0x08 // Get/Set target timeouts
|
||||
|
||||
//*****************************************************************************
|
||||
// %%% SRB Status %%%
|
||||
//*****************************************************************************
|
||||
|
||||
#define SS_PENDING 0x00 // SRB being processed
|
||||
#define SS_COMP 0x01 // SRB completed without error
|
||||
#define SS_ABORTED 0x02 // SRB aborted
|
||||
#define SS_ABORT_FAIL 0x03 // Unable to abort SRB
|
||||
#define SS_ERR 0x04 // SRB completed with error
|
||||
|
||||
#define SS_INVALID_CMD 0x80 // Invalid ASPI command
|
||||
#define SS_INVALID_HA 0x81 // Invalid host adapter number
|
||||
#define SS_NO_DEVICE 0x82 // SCSI device not installed
|
||||
|
||||
#define SS_INVALID_SRB 0xE0 // Invalid parameter set in SRB
|
||||
#define SS_OLD_MANAGER 0xE1 // ASPI manager doesn't support Windows
|
||||
#define SS_BUFFER_ALIGN 0xE1 // Buffer not aligned (replaces OLD_MANAGER in Win32)
|
||||
#define SS_ILLEGAL_MODE 0xE2 // Unsupported Windows mode
|
||||
#define SS_NO_ASPI 0xE3 // No ASPI managers resident
|
||||
#define SS_FAILED_INIT 0xE4 // ASPI for windows failed init
|
||||
#define SS_ASPI_IS_BUSY 0xE5 // No resources available to execute cmd
|
||||
#define SS_BUFFER_TO_BIG 0xE6 // Buffer size to big to handle!
|
||||
#define SS_MISMATCHED_COMPONENTS 0xE7 // The DLLs/EXEs of ASPI don't version check
|
||||
#define SS_NO_ADAPTERS 0xE8 // No host adapters to manage
|
||||
#define SS_INSUFFICIENT_RESOURCES 0xE9 // Couldn't allocate resources needed to init
|
||||
#define SS_ASPI_IS_SHUTDOWN 0xEA // Call came to ASPI after PROCESS_DETACH
|
||||
#define SS_BAD_INSTALL 0xEB // The DLL or other components are installed wrong
|
||||
|
||||
//*****************************************************************************
|
||||
// %%% Host Adapter Status %%%
|
||||
//*****************************************************************************
|
||||
|
||||
#define HASTAT_OK 0x00 // Host adapter did not detect an // error
|
||||
#define HASTAT_SEL_TO 0x11 // Selection Timeout
|
||||
#define HASTAT_DO_DU 0x12 // Data overrun data underrun
|
||||
#define HASTAT_BUS_FREE 0x13 // Unexpected bus free
|
||||
#define HASTAT_PHASE_ERR 0x14 // Target bus phase sequence // failure
|
||||
#define HASTAT_TIMEOUT 0x09 // Timed out while SRB was waiting to beprocessed.
|
||||
#define HASTAT_COMMAND_TIMEOUT 0x0B // Adapter timed out processing SRB.
|
||||
#define HASTAT_MESSAGE_REJECT 0x0D // While processing SRB, the // adapter received a MESSAGE
|
||||
#define HASTAT_BUS_RESET 0x0E // A bus reset was detected.
|
||||
#define HASTAT_PARITY_ERROR 0x0F // A parity error was detected.
|
||||
#define HASTAT_REQUEST_SENSE_FAILED 0x10 // The adapter failed in issuing
|
||||
|
||||
//*****************************************************************************
|
||||
// %%% SRB - HOST ADAPTER INQUIRY - SC_HA_INQUIRY (0) %%%
|
||||
//*****************************************************************************
|
||||
|
||||
typedef struct // Offset
|
||||
{ // HX/DEC
|
||||
BYTE SRB_Cmd; // 00/000 ASPI command code = SC_HA_INQUIRY
|
||||
BYTE SRB_Status; // 01/001 ASPI command status byte
|
||||
BYTE SRB_HaId; // 02/002 ASPI host adapter number
|
||||
BYTE SRB_Flags; // 03/003 ASPI request flags
|
||||
DWORD SRB_Hdr_Rsvd; // 04/004 Reserved, MUST = 0
|
||||
BYTE HA_Count; // 08/008 Number of host adapters present
|
||||
BYTE HA_SCSI_ID; // 09/009 SCSI ID of host adapter
|
||||
BYTE HA_ManagerId[16]; // 0A/010 String describing the manager
|
||||
BYTE HA_Identifier[16]; // 1A/026 String describing the host adapter
|
||||
BYTE HA_Unique[16]; // 2A/042 Host Adapter Unique parameters
|
||||
WORD HA_Rsvd1; // 3A/058 Reserved, MUST = 0
|
||||
}
|
||||
SRB_HAInquiry, *PSRB_HAInquiry, FAR *LPSRB_HAInquiry;
|
||||
|
||||
//*****************************************************************************
|
||||
// %%% SRB - GET DEVICE TYPE - SC_GET_DEV_TYPE (1) %%%
|
||||
//*****************************************************************************
|
||||
|
||||
typedef struct // Offset
|
||||
{ // HX/DEC
|
||||
BYTE SRB_Cmd; // 00/000 ASPI command code = SC_GET_DEV_TYPE
|
||||
BYTE SRB_Status; // 01/001 ASPI command status byte
|
||||
BYTE SRB_HaId; // 02/002 ASPI host adapter number
|
||||
BYTE SRB_Flags; // 03/003 Reserved, MUST = 0
|
||||
DWORD SRB_Hdr_Rsvd; // 04/004 Reserved, MUST = 0
|
||||
BYTE SRB_Target; // 08/008 Target's SCSI ID
|
||||
BYTE SRB_Lun; // 09/009 Target's LUN number
|
||||
BYTE SRB_DeviceType; // 0A/010 Target's peripheral device type
|
||||
BYTE SRB_Rsvd1; // 0B/011 Reserved, MUST = 0
|
||||
}
|
||||
SRB_GDEVBlock, *PSRB_GDEVBlock, FAR *LPSRB_GDEVBlock;
|
||||
|
||||
//*****************************************************************************
|
||||
// %%% SRB - EXECUTE SCSI COMMAND - SC_EXEC_SCSI_CMD (2) %%%
|
||||
//*****************************************************************************
|
||||
|
||||
typedef struct // Offset
|
||||
{ // HX/DEC
|
||||
BYTE SRB_Cmd; // 00/000 ASPI command code = SC_EXEC_SCSI_CMD
|
||||
BYTE SRB_Status; // 01/001 ASPI command status byte
|
||||
BYTE SRB_HaId; // 02/002 ASPI host adapter number
|
||||
BYTE SRB_Flags; // 03/003 ASPI request flags
|
||||
DWORD SRB_Hdr_Rsvd; // 04/004 Reserved
|
||||
BYTE SRB_Target; // 08/008 Target's SCSI ID
|
||||
BYTE SRB_Lun; // 09/009 Target's LUN number
|
||||
WORD SRB_Rsvd1; // 0A/010 Reserved for Alignment
|
||||
DWORD SRB_BufLen; // 0C/012 Data Allocation Length
|
||||
BYTE FAR *SRB_BufPointer; // 10/016 Data Buffer Pointer
|
||||
BYTE SRB_SenseLen; // 14/020 Sense Allocation Length
|
||||
BYTE SRB_CDBLen; // 15/021 CDB Length
|
||||
BYTE SRB_HaStat; // 16/022 Host Adapter Status
|
||||
BYTE SRB_TargStat; // 17/023 Target Status
|
||||
VOID FAR *SRB_PostProc; // 18/024 Post routine
|
||||
BYTE SRB_Rsvd2[20]; // 1C/028 Reserved, MUST = 0
|
||||
BYTE CDBByte[16]; // 30/048 SCSI CDB
|
||||
BYTE SenseArea[SENSE_LEN+2]; // 50/064 Request Sense buffer
|
||||
}
|
||||
SRB_ExecSCSICmd, *PSRB_ExecSCSICmd, FAR *LPSRB_ExecSCSICmd;
|
||||
|
||||
//*****************************************************************************
|
||||
// %%% SRB - ABORT AN SRB - SC_ABORT_SRB (3) %%%
|
||||
//*****************************************************************************
|
||||
|
||||
typedef struct // Offset
|
||||
{ // HX/DEC
|
||||
BYTE SRB_Cmd; // 00/000 ASPI command code = SC_ABORT_SRB
|
||||
BYTE SRB_Status; // 01/001 ASPI command status byte
|
||||
BYTE SRB_HaId; // 02/002 ASPI host adapter number
|
||||
BYTE SRB_Flags; // 03/003 Reserved
|
||||
DWORD SRB_Hdr_Rsvd; // 04/004 Reserved
|
||||
VOID FAR *SRB_ToAbort; // 08/008 Pointer to SRB to abort
|
||||
}
|
||||
SRB_Abort, *PSRB_Abort, FAR *LPSRB_Abort;
|
||||
|
||||
//*****************************************************************************
|
||||
// %%% SRB - BUS DEVICE RESET - SC_RESET_DEV (4) %%%
|
||||
//*****************************************************************************
|
||||
|
||||
typedef struct // Offset
|
||||
{ // HX/DEC
|
||||
BYTE SRB_Cmd; // 00/000 ASPI command code = SC_RESET_DEV
|
||||
BYTE SRB_Status; // 01/001 ASPI command status byte
|
||||
BYTE SRB_HaId; // 02/002 ASPI host adapter number
|
||||
BYTE SRB_Flags; // 03/003 ASPI request flags
|
||||
DWORD SRB_Hdr_Rsvd; // 04/004 Reserved
|
||||
BYTE SRB_Target; // 08/008 Target's SCSI ID
|
||||
BYTE SRB_Lun; // 09/009 Target's LUN number
|
||||
BYTE SRB_Rsvd1[12]; // 0A/010 Reserved for Alignment
|
||||
BYTE SRB_HaStat; // 16/022 Host Adapter Status
|
||||
BYTE SRB_TargStat; // 17/023 Target Status
|
||||
VOID FAR *SRB_PostProc; // 18/024 Post routine
|
||||
BYTE SRB_Rsvd2[36]; // 1C/028 Reserved, MUST = 0
|
||||
}
|
||||
SRB_BusDeviceReset, *PSRB_BusDeviceReset, FAR *LPSRB_BusDeviceReset;
|
||||
|
||||
//*****************************************************************************
|
||||
// %%% SRB - GET DISK INFORMATION - SC_GET_DISK_INFO %%%
|
||||
//*****************************************************************************
|
||||
|
||||
typedef struct // Offset
|
||||
{ // HX/DEC
|
||||
BYTE SRB_Cmd; // 00/000 ASPI command code = SC_GET_DISK_INFO
|
||||
BYTE SRB_Status; // 01/001 ASPI command status byte
|
||||
BYTE SRB_HaId; // 02/002 ASPI host adapter number
|
||||
BYTE SRB_Flags; // 03/003 Reserved, MUST = 0
|
||||
DWORD SRB_Hdr_Rsvd; // 04/004 Reserved, MUST = 0
|
||||
BYTE SRB_Target; // 08/008 Target's SCSI ID
|
||||
BYTE SRB_Lun; // 09/009 Target's LUN number
|
||||
BYTE SRB_DriveFlags; // 0A/010 Driver flags
|
||||
BYTE SRB_Int13HDriveInfo; // 0B/011 Host Adapter Status
|
||||
BYTE SRB_Heads; // 0C/012 Preferred number of heads translation
|
||||
BYTE SRB_Sectors; // 0D/013 Preferred number of sectors translation
|
||||
BYTE SRB_Rsvd1[10]; // 0E/014 Reserved, MUST = 0
|
||||
}
|
||||
SRB_GetDiskInfo, *PSRB_GetDiskInfo, FAR *LPSRB_GetDiskInfo;
|
||||
|
||||
//*****************************************************************************
|
||||
// %%% SRB - RESCAN SCSI BUS(ES) ON SCSIPORT %%%
|
||||
//*****************************************************************************
|
||||
|
||||
typedef struct // Offset
|
||||
{ // HX/DEC
|
||||
BYTE SRB_Cmd; // 00/000 ASPI command code = SC_RESCAN_SCSI_BUS
|
||||
BYTE SRB_Status; // 01/001 ASPI command status byte
|
||||
BYTE SRB_HaId; // 02/002 ASPI host adapter number
|
||||
BYTE SRB_Flags; // 03/003 Reserved, MUST = 0
|
||||
DWORD SRB_Hdr_Rsvd; // 04/004 Reserved, MUST = 0
|
||||
}
|
||||
SRB_RescanPort, *PSRB_RescanPort, FAR *LPSRB_RescanPort;
|
||||
|
||||
//*****************************************************************************
|
||||
// %%% SRB - GET/SET TARGET TIMEOUTS %%%
|
||||
//*****************************************************************************
|
||||
|
||||
typedef struct // Offset
|
||||
{ // HX/DEC
|
||||
BYTE SRB_Cmd; // 00/000 ASPI command code = SC_GETSET_TIMEOUTS
|
||||
BYTE SRB_Status; // 01/001 ASPI command status byte
|
||||
BYTE SRB_HaId; // 02/002 ASPI host adapter number
|
||||
BYTE SRB_Flags; // 03/003 ASPI request flags
|
||||
DWORD SRB_Hdr_Rsvd; // 04/004 Reserved, MUST = 0
|
||||
BYTE SRB_Target; // 08/008 Target's SCSI ID
|
||||
BYTE SRB_Lun; // 09/009 Target's LUN number
|
||||
DWORD SRB_Timeout; // 0A/010 Timeout in half seconds
|
||||
}
|
||||
SRB_GetSetTimeouts, *PSRB_GetSetTimeouts, FAR *LPSRB_GetSetTimeouts;
|
||||
|
||||
//*****************************************************************************
|
||||
// %%% ASPIBUFF - Structure For Controllng I/O Buffers %%%
|
||||
//*****************************************************************************
|
||||
|
||||
typedef struct tag_ASPI32BUFF // Offset
|
||||
{ // HX/DEC
|
||||
PBYTE AB_BufPointer; // 00/000 Pointer to the ASPI allocated buffer
|
||||
DWORD AB_BufLen; // 04/004 Length in bytes of the buffer
|
||||
DWORD AB_ZeroFill; // 08/008 Flag set to 1 if buffer should be zeroed
|
||||
DWORD AB_Reserved; // 0C/012 Reserved
|
||||
}
|
||||
ASPI32BUFF, *PASPI32BUFF, FAR *LPASPI32BUFF;
|
||||
|
||||
//*****************************************************************************
|
||||
// %%% TOC structures %%%
|
||||
//*****************************************************************************
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char reserved1;
|
||||
unsigned char cAdrCtrl;
|
||||
unsigned char cTrackNum;
|
||||
unsigned char reserved2;
|
||||
unsigned long lAddr;
|
||||
} TOC_TRACK;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short usTocDataLen;
|
||||
unsigned char cFirstTrack;
|
||||
unsigned char cLastTrack;
|
||||
TOC_TRACK tracks[100];
|
||||
} TOC, *PTOC, FAR *LPTOC;
|
||||
|
||||
//*****************************************************************************
|
||||
// %%% PROTOTYPES - User Callable ASPI for Win32 Functions %%%
|
||||
//*****************************************************************************
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BYTE SRB_Cmd;
|
||||
BYTE SRB_Status;
|
||||
BYTE SRB_HaId;
|
||||
BYTE SRB_Flags;
|
||||
DWORD SRB_Hdr_Rsvd;
|
||||
} SRB, *PSRB, FAR *LPSRB;
|
||||
|
||||
|
||||
#if defined(__BORLANDC__)
|
||||
|
||||
DWORD _import GetASPI32SupportInfo( void );
|
||||
DWORD _import SendASPI32Command( LPSRB );
|
||||
BOOL _import GetASPI32Buffer( PASPI32BUFF );
|
||||
BOOL _import FreeASPI32Buffer( PASPI32BUFF );
|
||||
BOOL _import TranslateASPI32Address( PDWORD, PDWORD );
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
|
||||
__declspec(dllimport) DWORD GetASPI32SupportInfo( void );
|
||||
__declspec(dllimport) DWORD SendASPI32Command( LPSRB );
|
||||
__declspec(dllimport) BOOL GetASPI32Buffer( PASPI32BUFF );
|
||||
__declspec(dllimport) BOOL FreeASPI32Buffer( PASPI32BUFF );
|
||||
__declspec(dllimport) BOOL TranslateASPI32Address( PDWORD, PDWORD );
|
||||
|
||||
#else
|
||||
|
||||
extern DWORD GetASPI32SupportInfo( void );
|
||||
extern DWORD GetASPI32Command( LPSRB );
|
||||
extern BOOL GetASPI32Buffer( PASPI32BUFF );
|
||||
extern BOOL FreeASPI32Buffer( PASPI32BUFF );
|
||||
extern BOOL TranslateASPI32Address( PDWORD, PDWORD );
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
** Restore compiler default packing and close off the C declarations.
|
||||
*/
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma option -a.
|
||||
#endif //__BORLANDC__
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma pack()
|
||||
#endif //_MSC_VER
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif //__cplusplus
|
||||
|
||||
#endif //__WNASPI32_H__
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2002 The DOSBox Team
|
||||
* Copyright (C) 2002-2003 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -42,6 +42,7 @@ Bitu errorlevel=1;
|
||||
|
||||
/* The whole load of startups for all the subfunctions */
|
||||
void MSG_Init(Section_prop *);
|
||||
void LOG_StartUp(void);
|
||||
void MEM_Init(Section *);
|
||||
void IO_Init(Section * );
|
||||
void CALLBACK_Init(Section*);
|
||||
@ -57,6 +58,7 @@ void CPU_Init(Section*);
|
||||
//void FPU_Init();
|
||||
void DMA_Init(Section*);
|
||||
void MIXER_Init(Section*);
|
||||
void MIDI_Init(Section*);
|
||||
void HARDWARE_Init(Section*);
|
||||
|
||||
|
||||
@ -65,20 +67,21 @@ void JOYSTICK_Init(Section*);
|
||||
void MOUSE_Init(Section*);
|
||||
void SBLASTER_Init(Section*);
|
||||
void GUS_Init(Section*);
|
||||
void MPU401_Init(Section*);
|
||||
void ADLIB_Init(Section*);
|
||||
void PCSPEAKER_Init(Section*);
|
||||
void TANDYSOUND_Init(Section*);
|
||||
void CMS_Init(Section*);
|
||||
void DISNEY_Init(Section*);
|
||||
|
||||
|
||||
|
||||
void PIC_Init(Section*);
|
||||
void TIMER_Init(Section*);
|
||||
void BIOS_Init(Section*);
|
||||
void DEBUG_Init(Section*);
|
||||
void CMOS_Init(Section*);
|
||||
|
||||
void MSCDEX_Init(Section*);
|
||||
|
||||
/* Dos Internal mostly */
|
||||
void EMS_Init(Section*);
|
||||
void XMS_Init(Section*);
|
||||
@ -158,6 +161,7 @@ void DOSBOX_Init(void) {
|
||||
secprop->Add_string("language","");
|
||||
#if C_DEBUG
|
||||
secprop->Add_int("warnings",4);
|
||||
LOG_StartUp();
|
||||
#else
|
||||
secprop->Add_int("warnings",0);
|
||||
#endif
|
||||
@ -172,8 +176,9 @@ void DOSBOX_Init(void) {
|
||||
secprop=control->AddSection_prop("render",&RENDER_Init);
|
||||
secprop->Add_int("frameskip",0);
|
||||
secprop->Add_bool("keepsmall",false);
|
||||
secprop->Add_string("snapshots","snapshots");
|
||||
|
||||
secprop->Add_string("snapshots","snaps");
|
||||
secprop->Add_string("scaler","none");
|
||||
|
||||
secprop=control->AddSection_prop("cpu",&CPU_Init);
|
||||
secprop->Add_int("cycles",1800);
|
||||
|
||||
@ -184,6 +189,17 @@ void DOSBOX_Init(void) {
|
||||
secprop->AddInitFunction(&JOYSTICK_Init);
|
||||
|
||||
secprop=control->AddSection_prop("mixer",&MIXER_Init);
|
||||
secprop->Add_bool("nosound",false);
|
||||
secprop->Add_int("freq",22050);
|
||||
secprop->Add_int("blocksize",2048);
|
||||
secprop->Add_string("wavedir","waves");
|
||||
|
||||
secprop=control->AddSection_prop("midi",&MIDI_Init);
|
||||
secprop->AddInitFunction(&MPU401_Init);
|
||||
secprop->Add_bool("mpu401",true);
|
||||
secprop->Add_string("device","default");
|
||||
secprop->Add_string("config","");
|
||||
|
||||
#if C_DEBUG
|
||||
secprop=control->AddSection_prop("debug",&DEBUG_Init);
|
||||
#endif
|
||||
@ -192,20 +208,23 @@ void DOSBOX_Init(void) {
|
||||
secprop->Add_int("irq",7);
|
||||
secprop->Add_int("dma",1);
|
||||
secprop->Add_int("hdma",5);
|
||||
secprop->Add_int("sbrate",22050);
|
||||
secprop->Add_bool("enabled",true);
|
||||
|
||||
secprop->AddInitFunction(&ADLIB_Init);
|
||||
secprop->Add_bool("adlib",true);
|
||||
secprop->AddInitFunction(&CMS_Init);
|
||||
secprop->Add_bool("cms",false);
|
||||
secprop->Add_bool("cms",false);
|
||||
secprop->Add_int("cmsrate",22050);
|
||||
|
||||
// secprop=control->AddSection_prop("gus",&GUS_Init);
|
||||
|
||||
|
||||
secprop=control->AddSection_prop("disney",&DISNEY_Init);
|
||||
secprop->Add_bool("enabled",true);
|
||||
|
||||
secprop=control->AddSection_prop("speaker",&PCSPEAKER_Init);
|
||||
secprop->Add_bool("enabled",true);
|
||||
secprop->Add_bool("sinewave",false);
|
||||
secprop->Add_int("pcrate",22050);
|
||||
secprop->AddInitFunction(&TANDYSOUND_Init);
|
||||
secprop->Add_bool("tandy",false);
|
||||
|
||||
@ -220,8 +239,11 @@ void DOSBOX_Init(void) {
|
||||
secprop->AddInitFunction(&XMS_Init);
|
||||
secprop->Add_int("xmssize",8);
|
||||
|
||||
// Mscdex
|
||||
secprop->AddInitFunction(&MSCDEX_Init);
|
||||
|
||||
secline=control->AddSection_line("autoexec",&AUTOEXEC_Init);
|
||||
|
||||
|
||||
control->SetStartUp(&SHELL_Init);
|
||||
|
||||
#if C_FPU
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Makefile.in generated by automake 1.6.1 from Makefile.am.
|
||||
# Makefile.in generated by automake 1.6.3 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
|
||||
@ -49,6 +49,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = @program_transform_name@
|
||||
@ -64,6 +65,8 @@ host_triplet = @host@
|
||||
EXEEXT = @EXEEXT@
|
||||
OBJEXT = @OBJEXT@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
ALSA_CFLAGS = @ALSA_CFLAGS@
|
||||
ALSA_LIBS = @ALSA_LIBS@
|
||||
AMTAR = @AMTAR@
|
||||
AWK = @AWK@
|
||||
CC = @CC@
|
||||
@ -205,7 +208,7 @@ top_distdir = ../..
|
||||
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@for file in $(DISTFILES); do \
|
||||
@list='$(DISTFILES)'; for file in $$list; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
|
||||
@ -250,7 +253,7 @@ mostlyclean-generic:
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]*
|
||||
-rm -f Makefile $(CONFIG_CLEAN_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
|
@ -1,5 +1,6 @@
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||
|
||||
noinst_LIBRARIES = libgui.a
|
||||
libgui_a_SOURCES = sdlmain.cpp render.cpp render_support.h
|
||||
libgui_a_SOURCES = sdlmain.cpp render.cpp render_normal.h render_scale2x.h \
|
||||
midi.cpp midi_win32.h midi_oss.h midi_coreaudio.h
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Makefile.in generated by automake 1.6.1 from Makefile.am.
|
||||
# Makefile.in generated by automake 1.6.3 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
|
||||
@ -49,6 +49,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = @program_transform_name@
|
||||
@ -64,6 +65,8 @@ host_triplet = @host@
|
||||
EXEEXT = @EXEEXT@
|
||||
OBJEXT = @OBJEXT@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
ALSA_CFLAGS = @ALSA_CFLAGS@
|
||||
ALSA_LIBS = @ALSA_LIBS@
|
||||
AMTAR = @AMTAR@
|
||||
AWK = @AWK@
|
||||
CC = @CC@
|
||||
@ -84,7 +87,9 @@ install_sh = @install_sh@
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||
|
||||
noinst_LIBRARIES = libgui.a
|
||||
libgui_a_SOURCES = sdlmain.cpp render.cpp render_support.h
|
||||
libgui_a_SOURCES = sdlmain.cpp render.cpp render_normal.h render_scale2x.h \
|
||||
midi.cpp midi_win32.h midi_oss.h midi_coreaudio.h
|
||||
|
||||
subdir = src/gui
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
CONFIG_HEADER = $(top_builddir)/config.h
|
||||
@ -93,7 +98,7 @@ LIBRARIES = $(noinst_LIBRARIES)
|
||||
|
||||
libgui_a_AR = $(AR) cru
|
||||
libgui_a_LIBADD =
|
||||
am_libgui_a_OBJECTS = sdlmain.$(OBJEXT) render.$(OBJEXT)
|
||||
am_libgui_a_OBJECTS = sdlmain.$(OBJEXT) render.$(OBJEXT) midi.$(OBJEXT)
|
||||
libgui_a_OBJECTS = $(am_libgui_a_OBJECTS)
|
||||
|
||||
DEFS = @DEFS@
|
||||
@ -103,7 +108,8 @@ LDFLAGS = @LDFLAGS@
|
||||
LIBS = @LIBS@
|
||||
depcomp = $(SHELL) $(top_srcdir)/depcomp
|
||||
am__depfiles_maybe = depfiles
|
||||
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/render.Po ./$(DEPDIR)/sdlmain.Po
|
||||
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/midi.Po ./$(DEPDIR)/render.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/sdlmain.Po
|
||||
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
|
||||
CXXLD = $(CXX)
|
||||
@ -144,6 +150,7 @@ mostlyclean-compile:
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/midi.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/render.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sdlmain.Po@am__quote@
|
||||
|
||||
@ -205,7 +212,7 @@ top_distdir = ../..
|
||||
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@for file in $(DISTFILES); do \
|
||||
@list='$(DISTFILES)'; for file in $$list; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
|
||||
@ -250,7 +257,7 @@ mostlyclean-generic:
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]*
|
||||
-rm -f Makefile $(CONFIG_CLEAN_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
|
180
src/gui/midi.cpp
Normal file
180
src/gui/midi.cpp
Normal file
@ -0,0 +1,180 @@
|
||||
/*
|
||||
* Copyright (C) 2002-2003 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "dosbox.h"
|
||||
#include "cross.h"
|
||||
#include "support.h"
|
||||
#include "setup.h"
|
||||
|
||||
#define SYSEX_SIZE 1024
|
||||
|
||||
Bit8u MIDI_evt_len[256] = {
|
||||
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x00
|
||||
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x10
|
||||
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x20
|
||||
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x30
|
||||
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x40
|
||||
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x50
|
||||
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x60
|
||||
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0, // 0x70
|
||||
|
||||
3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0x80
|
||||
3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0x90
|
||||
3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xa0
|
||||
3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xb0
|
||||
|
||||
2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, // 0xc0
|
||||
2,2,2,2, 2,2,2,2, 2,2,2,2, 2,2,2,2, // 0xd0
|
||||
|
||||
3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3, // 0xe0
|
||||
|
||||
0,2,3,2, 0,0,1,1, 1,0,1,1, 1,0,1,1 // 0xf0
|
||||
};
|
||||
|
||||
class MidiHandler;
|
||||
|
||||
MidiHandler * handler_list=0;
|
||||
|
||||
class MidiHandler {
|
||||
public:
|
||||
MidiHandler() {
|
||||
next=handler_list;
|
||||
handler_list=this;
|
||||
};
|
||||
virtual bool Open(const char * conf) { return true; };
|
||||
virtual void Close(void) {};
|
||||
virtual void PlayMsg(Bit32u msg) {};
|
||||
virtual void PlaySysex(Bit8u * sysex,Bitu len) {};
|
||||
virtual char * GetName(void) { return "none"; };
|
||||
MidiHandler * next;
|
||||
};
|
||||
|
||||
MidiHandler Midi_none;
|
||||
|
||||
/* Include different midi drivers, lowest ones get checked first for default */
|
||||
|
||||
#if defined(MACOSX)
|
||||
|
||||
#include "midi_coreaudio.h"
|
||||
|
||||
#elif defined (WIN32)
|
||||
|
||||
#include "midi_win32.h"
|
||||
|
||||
#else
|
||||
|
||||
#include "midi_oss.h"
|
||||
|
||||
#endif
|
||||
|
||||
static struct {
|
||||
Bitu status;
|
||||
Bitu cmd_len;
|
||||
Bitu cmd_pos;
|
||||
|
||||
Bit32u cmd_msg;
|
||||
Bit8u data[4];
|
||||
struct {
|
||||
Bit8u buf[SYSEX_SIZE];
|
||||
Bitu used;
|
||||
bool active;
|
||||
} sysex;
|
||||
bool available;
|
||||
MidiHandler * handler;
|
||||
} midi;
|
||||
|
||||
void MIDI_RawOutByte(Bit8u data) {
|
||||
/* Test for a new status byte */
|
||||
if (midi.sysex.active && !(data&0x80)) {
|
||||
if (midi.sysex.used<(SYSEX_SIZE-1)) midi.sysex.buf[midi.sysex.used++]=data;
|
||||
return;
|
||||
} else if (data&0x80) {
|
||||
if (midi.sysex.active) {
|
||||
/* Play a sysex message */
|
||||
midi.sysex.buf[midi.sysex.used++]=0xf7;
|
||||
midi.handler->PlaySysex(midi.sysex.buf,midi.sysex.used);
|
||||
LOG(0,"Sysex message size %d",midi.sysex.used);
|
||||
midi.sysex.active=false;
|
||||
if (data==0xf7) return;
|
||||
}
|
||||
midi.status=data;
|
||||
midi.cmd_pos=0;
|
||||
midi.cmd_msg=0;
|
||||
if (midi.status==0xf0) {
|
||||
midi.sysex.active=true;
|
||||
midi.sysex.buf[0]=0xf0;
|
||||
midi.sysex.used=1;
|
||||
return;
|
||||
}
|
||||
midi.cmd_len=MIDI_evt_len[data];
|
||||
}
|
||||
midi.cmd_msg|=data << (8 * midi.cmd_pos);
|
||||
midi.cmd_pos++;
|
||||
if (midi.cmd_pos >= midi.cmd_len) {
|
||||
midi.handler->PlayMsg(midi.cmd_msg);
|
||||
midi.cmd_msg=midi.status;
|
||||
midi.cmd_pos=1;
|
||||
}
|
||||
}
|
||||
|
||||
bool MIDI_Available(void) {
|
||||
return midi.available;
|
||||
}
|
||||
|
||||
void MIDI_Init(Section * sec) {
|
||||
Section_prop * section=static_cast<Section_prop *>(sec);
|
||||
MSG_Add("MIDI_CONFIGFILE_HELP","Set midi output device,alsa,oss,win32,coreaudio,none\n");
|
||||
const char * dev=section->Get_string("device");
|
||||
const char * conf=section->Get_string("config");
|
||||
/* If device = "default" go for first handler that works */
|
||||
MidiHandler * handler;
|
||||
if (!strcasecmp(dev,"default")) goto getdefault;
|
||||
handler=handler_list;
|
||||
while (handler) {
|
||||
if (!strcasecmp(dev,handler->GetName())) {
|
||||
if (!handler->Open(conf)) {
|
||||
LOG_MSG("MIDI:Can't open device:%s with config:%s.",dev,conf);
|
||||
goto getdefault;
|
||||
}
|
||||
midi.handler=handler;
|
||||
midi.available=true;
|
||||
LOG_MSG("MIDI:Opened device:%s",handler->GetName());
|
||||
return;
|
||||
}
|
||||
handler=handler->next;
|
||||
}
|
||||
LOG_MSG("MIDI:Can't find device:%s, finding default handler.",dev);
|
||||
getdefault:
|
||||
handler=handler_list;
|
||||
while (handler) {
|
||||
if (handler->Open(conf)) {
|
||||
midi.available=true;
|
||||
midi.handler=handler;
|
||||
LOG_MSG("MIDI:Opened device:%s",handler->GetName());
|
||||
return;
|
||||
}
|
||||
handler=handler->next;
|
||||
}
|
||||
/* This shouldn't be possible */
|
||||
midi.available=false;
|
||||
}
|
||||
|
92
src/gui/midi_coreaudio.h
Normal file
92
src/gui/midi_coreaudio.h
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (C) 2002-2003 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <AudioUnit/AudioUnit.h>
|
||||
|
||||
class MidiHandler_coreaudio : public MidiHandler {
|
||||
private:
|
||||
AudioUnit m_musicDevice;
|
||||
AudioUnit m_outputUnit;
|
||||
public:
|
||||
MidiHandler_coreaudio() : m_musicDevice(0), m_outputUnit(0) {}
|
||||
char * GetName(void) { return "coreaudio"; }
|
||||
bool Open(const char * conf) {
|
||||
int err;
|
||||
AudioUnitConnection auconnect;
|
||||
ComponentDescription compdesc;
|
||||
Component compid;
|
||||
|
||||
if (m_outputUnit)
|
||||
return false;
|
||||
|
||||
// Open the Music Device
|
||||
compdesc.componentType = kAudioUnitComponentType;
|
||||
compdesc.componentSubType = kAudioUnitSubType_MusicDevice;
|
||||
compdesc.componentManufacturer = kAudioUnitID_DLSSynth;
|
||||
compdesc.componentFlags = 0;
|
||||
compdesc.componentFlagsMask = 0;
|
||||
compid = FindNextComponent(NULL, &compdesc);
|
||||
m_musicDevice = (AudioUnit) OpenComponent(compid);
|
||||
|
||||
// open the output unit
|
||||
m_outputUnit = (AudioUnit) OpenDefaultComponent(kAudioUnitComponentType, kAudioUnitSubType_Output);
|
||||
|
||||
// connect the units
|
||||
auconnect.sourceAudioUnit = m_musicDevice;
|
||||
auconnect.sourceOutputNumber = 0;
|
||||
auconnect.destInputNumber = 0;
|
||||
err =
|
||||
AudioUnitSetProperty(m_outputUnit, kAudioUnitProperty_MakeConnection, kAudioUnitScope_Input, 0,
|
||||
(void *)&auconnect, sizeof(AudioUnitConnection));
|
||||
|
||||
// initialize the units
|
||||
AudioUnitInitialize(m_musicDevice);
|
||||
AudioUnitInitialize(m_outputUnit);
|
||||
|
||||
// start the output
|
||||
AudioOutputUnitStart(m_outputUnit);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Close(void) {
|
||||
if (m_outputUnit) {
|
||||
AudioOutputUnitStop(m_outputUnit);
|
||||
CloseComponent(m_outputUnit);
|
||||
m_outputUnit = 0;
|
||||
}
|
||||
if (m_musicDevice) {
|
||||
CloseComponent(m_musicDevice);
|
||||
m_musicDevice = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void PlayMsg(Bit32u msg) {
|
||||
MusicDeviceMIDIEvent(m_musicDevice,
|
||||
(msg & 0x000000FF),
|
||||
(msg & 0x0000FF00) >> 8,
|
||||
(msg & 0x00FF0000) >> 16,
|
||||
0);
|
||||
}
|
||||
|
||||
void PlaySysex(Bit8u * sysex, Bitu len) {
|
||||
MusicDeviceSysEx(m_musicDevice, sysex, len);
|
||||
}
|
||||
};
|
||||
|
||||
MidiHandler_coreaudio Midi_coreaudio;
|
76
src/gui/midi_oss.h
Normal file
76
src/gui/midi_oss.h
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) 2002-2003 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <fcntl.h>
|
||||
#define SEQ_MIDIPUTC 5
|
||||
|
||||
class MidiHandler_oss: public MidiHandler {
|
||||
private:
|
||||
int device;
|
||||
Bit8u device_num;
|
||||
bool isOpen;
|
||||
public:
|
||||
MidiHandler_oss() : isOpen(false),MidiHandler() {};
|
||||
char * GetName(void) { return "oss";};
|
||||
bool Open(const char * conf) {
|
||||
char devname[512];
|
||||
if (conf && conf[0]) strncpy(devname,conf,512);
|
||||
else strcpy(devname,"/dev/sequencer");
|
||||
char * devfind=(strrchr(devname,','));
|
||||
if (devfind) {
|
||||
*devfind++=0;
|
||||
device_num=atoi(devfind);
|
||||
} else device_num=0;
|
||||
if (isOpen) return false;
|
||||
device=open(devname, O_WRONLY, 0);
|
||||
if (device<0) return false;
|
||||
return true;
|
||||
};
|
||||
void Close(void) {
|
||||
if (!isOpen) return;
|
||||
if (device>0) close(device);
|
||||
};
|
||||
void PlayMsg(Bit32u msg) {
|
||||
Bit8u buf[128];Bitu pos=0;
|
||||
Bitu len=MIDI_evt_len[msg & 0xff];
|
||||
for (;len>0;len--) {
|
||||
buf[pos++] = SEQ_MIDIPUTC;
|
||||
buf[pos++] = msg & 0xff;
|
||||
buf[pos++] = device_num;
|
||||
buf[pos++] = 0;
|
||||
msg >>=8;
|
||||
}
|
||||
write(device,buf,pos);
|
||||
};
|
||||
void PlaySysex(Bit8u * sysex,Bitu len) {
|
||||
Bit8u buf[SYSEX_SIZE*4];Bitu pos=0;
|
||||
for (;len>0;len--) {
|
||||
buf[pos++] = SEQ_MIDIPUTC;
|
||||
buf[pos++] = *sysex++;
|
||||
buf[pos++] = device_num;
|
||||
buf[pos++] = 0;
|
||||
}
|
||||
write(device,buf,pos);
|
||||
}
|
||||
};
|
||||
|
||||
MidiHandler_oss Midi_oss;
|
||||
|
||||
|
||||
|
||||
|
73
src/gui/midi_win32.h
Normal file
73
src/gui/midi_win32.h
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (C) 2002-2003 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
|
||||
class MidiHandler_win32: public MidiHandler {
|
||||
private:
|
||||
HMIDIOUT m_out;
|
||||
MIDIHDR m_hdr;
|
||||
HANDLE m_event;
|
||||
bool isOpen;
|
||||
public:
|
||||
MidiHandler_win32() : isOpen(false),MidiHandler() {};
|
||||
char * GetName(void) { return "win32";};
|
||||
bool Open(const char * conf) {
|
||||
if (isOpen) return false;
|
||||
m_event = CreateEvent (NULL, true, true, NULL);
|
||||
MMRESULT res = midiOutOpen(&m_out, MIDI_MAPPER, (DWORD)m_event, 0, CALLBACK_EVENT);
|
||||
if (res != MMSYSERR_NOERROR) return false;
|
||||
isOpen=true;
|
||||
return true;
|
||||
};
|
||||
void Close(void) {
|
||||
if (!isOpen) return;
|
||||
isOpen=false;
|
||||
midiOutClose(m_out);
|
||||
CloseHandle (m_event);
|
||||
};
|
||||
void PlayMsg(Bit32u msg) {
|
||||
midiOutShortMsg(m_out, msg);
|
||||
};
|
||||
void PlaySysex(Bit8u * sysex,Bitu len) {
|
||||
if (WaitForSingleObject (m_event, 2000) == WAIT_TIMEOUT) {
|
||||
LOG(LOG_MISC|LOG_ERROR,"Can't send midi message");
|
||||
return;
|
||||
}
|
||||
midiOutUnprepareHeader (m_out, &m_hdr, sizeof (m_hdr));
|
||||
|
||||
m_hdr.lpData = (char *) sysex;
|
||||
m_hdr.dwBufferLength = len ;
|
||||
m_hdr.dwBytesRecorded = len ;
|
||||
m_hdr.dwUser = 0;
|
||||
|
||||
MMRESULT result = midiOutPrepareHeader (m_out, &m_hdr, sizeof (m_hdr));
|
||||
if (result != MMSYSERR_NOERROR) return;
|
||||
ResetEvent (m_event);
|
||||
result = midiOutLongMsg (m_out,&m_hdr,sizeof(m_hdr));
|
||||
if (result != MMSYSERR_NOERROR) {
|
||||
SetEvent (m_event);
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
MidiHandler_win32 Midi_win32;
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2002 The DOSBox Team
|
||||
* Copyright (C) 2002-2003 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -16,7 +16,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <png.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include "dosbox.h"
|
||||
@ -25,12 +25,10 @@
|
||||
#include "setup.h"
|
||||
#include "keyboard.h"
|
||||
#include "cross.h"
|
||||
|
||||
#include "support.h"
|
||||
|
||||
#define MAX_RES 2048
|
||||
|
||||
typedef void (* RENDER_Part_Handler)(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy);
|
||||
|
||||
struct PalData {
|
||||
struct {
|
||||
Bit8u red;
|
||||
@ -55,17 +53,16 @@ static struct {
|
||||
Bitu pitch;
|
||||
Bitu flags;
|
||||
float ratio;
|
||||
RENDER_Part_Handler part_handler;
|
||||
RENDER_Draw_Handler draw_handler;
|
||||
} src;
|
||||
struct {
|
||||
Bitu width;
|
||||
Bitu height;
|
||||
Bitu pitch;
|
||||
Bitu next_line;
|
||||
Bitu next_pixel;
|
||||
Bitu bpp; /* The type of BPP the operation requires for input */
|
||||
RENDER_Operation want_type;
|
||||
RENDER_Operation type;
|
||||
RENDER_Operation want_type;
|
||||
RENDER_Part_Handler part_handler;
|
||||
void * dest;
|
||||
void * buffer;
|
||||
void * pixels;
|
||||
@ -76,6 +73,13 @@ static struct {
|
||||
} frameskip;
|
||||
Bitu flags;
|
||||
PalData pal;
|
||||
#if (C_SSHOT)
|
||||
struct {
|
||||
RENDER_Operation type;
|
||||
Bitu pitch;
|
||||
const char * dir;
|
||||
} shot;
|
||||
#endif
|
||||
bool keep_small;
|
||||
bool screenshot;
|
||||
bool active;
|
||||
@ -85,9 +89,12 @@ static struct {
|
||||
static void RENDER_ResetPal(void);
|
||||
|
||||
/* Include the different rendering routines */
|
||||
#include "render_support.h"
|
||||
#include "render_normal.h"
|
||||
#include "render_scale2x.h"
|
||||
|
||||
static const char * snapshots_dir;
|
||||
|
||||
#if (C_SSHOT)
|
||||
#include <png.h>
|
||||
|
||||
/* Take a screenshot of the data that should be rendered */
|
||||
static void TakeScreenShot(Bit8u * bitmap) {
|
||||
@ -99,18 +106,10 @@ static void TakeScreenShot(Bit8u * bitmap) {
|
||||
png_color palette[256];
|
||||
Bitu i;
|
||||
|
||||
/* First try to alloacte the png structures */
|
||||
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,NULL, NULL);
|
||||
if (!png_ptr) return;
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
if (!info_ptr) {
|
||||
png_destroy_write_struct(&png_ptr,(png_infopp)NULL);
|
||||
return;
|
||||
}
|
||||
/* Find a filename to open */
|
||||
dir=opendir(snapshots_dir);
|
||||
dir=opendir(render.shot.dir);
|
||||
if (!dir) {
|
||||
LOG_WARN("Can't open snapshot dir %s",snapshots_dir);
|
||||
LOG_MSG("Can't open snapshot directory %s",render.shot.dir);
|
||||
return;
|
||||
}
|
||||
while (dir_ent=readdir(dir)) {
|
||||
@ -125,14 +124,24 @@ static void TakeScreenShot(Bit8u * bitmap) {
|
||||
if (num>=last) last=num+1;
|
||||
}
|
||||
closedir(dir);
|
||||
sprintf(file_name,"%s%csnap%05d.png",snapshots_dir,CROSS_FILESPLIT,last);
|
||||
/* Open the actual file */
|
||||
sprintf(file_name,"%s%csnap%04d.png",render.shot.dir,CROSS_FILESPLIT,last);
|
||||
/* Open the actual file */
|
||||
FILE * fp=fopen(file_name,"wb");
|
||||
if (!fp) {
|
||||
LOG_WARN("Can't open snapshot file %s",file_name);
|
||||
LOG_MSG("Can't open file %s for snapshot",file_name);
|
||||
return;
|
||||
}
|
||||
/* Finalize the initing of png library */
|
||||
|
||||
/* First try to alloacte the png structures */
|
||||
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,NULL, NULL);
|
||||
if (!png_ptr) return;
|
||||
info_ptr = png_create_info_struct(png_ptr);
|
||||
if (!info_ptr) {
|
||||
png_destroy_write_struct(&png_ptr,(png_infopp)NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Finalize the initing of png library */
|
||||
png_init_io(png_ptr, fp);
|
||||
png_set_compression_level(png_ptr,Z_BEST_COMPRESSION);
|
||||
|
||||
@ -161,7 +170,7 @@ static void TakeScreenShot(Bit8u * bitmap) {
|
||||
/*Allocate an array of scanline pointers*/
|
||||
row_pointers=(png_bytep*)malloc(render.src.height*sizeof(png_bytep));
|
||||
for (i=0;i<render.src.height;i++) {
|
||||
row_pointers[i]=(bitmap+i*render.src.pitch);
|
||||
row_pointers[i]=(bitmap+i*render.src.width);
|
||||
}
|
||||
/*tell the png library what to encode.*/
|
||||
png_set_rows(png_ptr, info_ptr, row_pointers);
|
||||
@ -177,8 +186,15 @@ static void TakeScreenShot(Bit8u * bitmap) {
|
||||
|
||||
/*clean up dynamically allocated RAM.*/
|
||||
free(row_pointers);
|
||||
LOG_MSG("Took snapshot in file %s",file_name);
|
||||
}
|
||||
|
||||
static void EnableScreenShot(void) {
|
||||
render.shot.type=render.op.type;
|
||||
render.op.type=OP_Shot;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* This could go kinda bad with multiple threads */
|
||||
@ -224,36 +240,40 @@ void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue) {
|
||||
if (render.pal.last<entry) render.pal.last=entry;
|
||||
}
|
||||
|
||||
bool RENDER_StartUpdate(void) {
|
||||
void RENDER_DoUpdate(void) {
|
||||
if (render.frameskip.count<render.frameskip.max) {
|
||||
render.frameskip.count++;
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
render.frameskip.count=0;
|
||||
if (render.src.bpp==8) Check_Palette();
|
||||
switch (render.op.type) {
|
||||
case OP_None:
|
||||
render.op.dest=render.op.pixels=GFX_StartUpdate();
|
||||
break;
|
||||
}
|
||||
if (render.op.dest) return true;
|
||||
else return false;
|
||||
GFX_DoUpdate();
|
||||
}
|
||||
|
||||
void RENDER_EndUpdate(void) {
|
||||
static void RENDER_DrawScreen(void * data) {
|
||||
switch (render.op.type) {
|
||||
doagain:
|
||||
case OP_None:
|
||||
/* Nothing to be done */
|
||||
render.op.pixels=0;
|
||||
render.op.dest=render.op.pixels=data;
|
||||
render.src.draw_handler(render.op.part_handler);
|
||||
break;
|
||||
case OP_Scale2x:
|
||||
render.op.dest=render.op.pixels=data;
|
||||
render.src.draw_handler(render.op.part_handler);
|
||||
break;
|
||||
#if (C_SSHOT)
|
||||
case OP_Shot:
|
||||
render.shot.pitch=render.op.pitch;
|
||||
render.op.pitch=render.src.width;
|
||||
render.op.pixels=malloc(render.src.width*render.src.height);
|
||||
render.src.draw_handler(Normal_DN_8);
|
||||
TakeScreenShot((Bit8u *)render.op.pixels);
|
||||
free(render.op.pixels);
|
||||
render.op.pitch=render.shot.pitch;
|
||||
render.op.type=render.shot.type;
|
||||
goto doagain;
|
||||
#endif
|
||||
}
|
||||
GFX_EndUpdate();
|
||||
}
|
||||
|
||||
/* Update the data ready to be sent out for blitting onto the screen */
|
||||
void RENDER_Part(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) {
|
||||
(render.src.part_handler)(src,x,y,dx,dy);
|
||||
return;
|
||||
}
|
||||
|
||||
static void RENDER_Resize(Bitu * width,Bitu * height) {
|
||||
@ -268,46 +288,71 @@ static void RENDER_Resize(Bitu * width,Bitu * height) {
|
||||
}
|
||||
}
|
||||
|
||||
void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,float ratio,Bitu flags) {
|
||||
void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,float ratio,Bitu flags,RENDER_Draw_Handler draw_handler) {
|
||||
if ((!width) || (!height) || (!pitch)) {
|
||||
render.active=false;return;
|
||||
}
|
||||
GFX_Stop();
|
||||
render.src.width=width;
|
||||
render.src.height=height;
|
||||
render.src.bpp=bpp;
|
||||
render.src.pitch=pitch;
|
||||
render.src.ratio=ratio;
|
||||
render.src.flags=flags;
|
||||
render.src.draw_handler=draw_handler;
|
||||
|
||||
GFX_ModeCallBack callback;
|
||||
GFX_ModeCallBack mode_callback=0;
|
||||
switch (render.op.want_type) {
|
||||
|
||||
case OP_None:
|
||||
normalop:
|
||||
switch (render.src.flags) {
|
||||
case DoubleNone:break;
|
||||
case DoubleWidth:width*=2;break;
|
||||
case DoubleHeight:height*=2;break;
|
||||
case DoubleNone:
|
||||
flags=0;
|
||||
break;
|
||||
case DoubleWidth:
|
||||
width*=2;
|
||||
flags=GFX_SHADOW;
|
||||
break;
|
||||
case DoubleHeight:
|
||||
height*=2;
|
||||
flags=0;
|
||||
break;
|
||||
case DoubleBoth:
|
||||
if (render.keep_small) {
|
||||
render.src.flags=0;
|
||||
flags=0;
|
||||
} else {
|
||||
width*=2;height*=2;
|
||||
flags=GFX_SHADOW;
|
||||
}
|
||||
break;
|
||||
}
|
||||
flags=0;
|
||||
callback=Render_Normal_CallBack;
|
||||
mode_callback=Render_Normal_CallBack;
|
||||
break;
|
||||
case OP_Scale2x:
|
||||
switch (render.src.flags) {
|
||||
case DoubleBoth:
|
||||
if (render.keep_small) goto normalop;
|
||||
mode_callback=Render_Scale2x_CallBack;
|
||||
width*=2;height*=2;
|
||||
#if defined (SCALE2X_NORMAL)
|
||||
flags=GFX_SHADOW;
|
||||
#elif defined (SCALE2X_MMX)
|
||||
flags=GFX_FIXED_BPP;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
goto normalop;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
goto normalop;
|
||||
|
||||
}
|
||||
GFX_SetSize(width,height,bpp,flags,callback);
|
||||
}
|
||||
|
||||
static void EnableScreenShot(void) {
|
||||
render.screenshot=true;
|
||||
GFX_SetSize(width,height,bpp,flags,mode_callback,RENDER_DrawScreen);
|
||||
GFX_Start();
|
||||
}
|
||||
|
||||
static void IncreaseFrameSkip(void) {
|
||||
@ -320,18 +365,32 @@ static void DecreaseFrameSkip(void) {
|
||||
LOG_MSG("Frame Skip at %d",render.frameskip.max);
|
||||
}
|
||||
|
||||
|
||||
void RENDER_Init(Section * sec) {
|
||||
MSG_Add("RENDER_CONFIGFILE_HELP","Available scalers: scale2x, none\n");
|
||||
Section_prop * section=static_cast<Section_prop *>(sec);
|
||||
snapshots_dir=section->Get_string("snapshots");
|
||||
|
||||
render.pal.first=256;
|
||||
render.pal.last=0;
|
||||
render.keep_small=section->Get_bool("keepsmall");
|
||||
render.frameskip.max=section->Get_int("frameskip");
|
||||
render.frameskip.count=0;
|
||||
KEYBOARD_AddEvent(KBD_f5,CTRL_PRESSED,EnableScreenShot);
|
||||
KEYBOARD_AddEvent(KBD_f7,CTRL_PRESSED,DecreaseFrameSkip);
|
||||
KEYBOARD_AddEvent(KBD_f8,CTRL_PRESSED,IncreaseFrameSkip);
|
||||
#if (C_SSHOT)
|
||||
render.shot.dir=section->Get_string("snapshots");
|
||||
KEYBOARD_AddEvent(KBD_f5,KBD_MOD_CTRL,EnableScreenShot);
|
||||
#endif
|
||||
const char * scaler;std::string cline;
|
||||
if (control->cmdline->FindString("-scaler",cline,false)) {
|
||||
scaler=cline.c_str();
|
||||
} else {
|
||||
scaler=section->Get_string("scaler");
|
||||
}
|
||||
if (!strcasecmp(scaler,"none")) render.op.want_type=OP_None;
|
||||
else if (!strcasecmp(scaler,"scale2x")) render.op.want_type=OP_Scale2x;
|
||||
else {
|
||||
render.op.want_type=OP_None;
|
||||
LOG_MSG("Illegal scaler type %s,falling back to none.",scaler);
|
||||
}
|
||||
KEYBOARD_AddEvent(KBD_f7,KBD_MOD_CTRL,DecreaseFrameSkip);
|
||||
KEYBOARD_AddEvent(KBD_f8,KBD_MOD_CTRL,IncreaseFrameSkip);
|
||||
}
|
||||
|
||||
|
182
src/gui/render_normal.h
Normal file
182
src/gui/render_normal.h
Normal file
@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright (C) 2002-2003 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#define LOOPSIZE 4
|
||||
|
||||
#define SIZE_8 1
|
||||
#define SIZE_16 2
|
||||
#define SIZE_32 4
|
||||
|
||||
#define MAKE_8(FROM) Bit8u val=*(Bit8u *)(FROM);
|
||||
#define MAKE_16(FROM) Bit16u val=render.pal.lookup.bpp16[*(Bit8u *)(FROM)];
|
||||
#define MAKE_32(FROM) Bit32u val=render.pal.lookup.bpp32[*(Bit8u *)(FROM)];
|
||||
|
||||
#define SAVE_8(WHERE) *(Bit8u *)(WHERE)=val;
|
||||
#define SAVE_16(WHERE) *(Bit16u *)(WHERE)=val;
|
||||
#define SAVE_32(WHERE) *(Bit32u *)(WHERE)=val;
|
||||
|
||||
#define LINES_DN 1
|
||||
#define LINES_DW 1
|
||||
#define LINES_DH 2
|
||||
#define LINES_DB 2
|
||||
|
||||
#define PIXELS_DN 1
|
||||
#define PIXELS_DW 2
|
||||
#define PIXELS_DH 1
|
||||
#define PIXELS_DB 2
|
||||
|
||||
#define NORMAL_DN(BPP,FROM,DEST) \
|
||||
MAKE_ ## BPP(FROM); \
|
||||
SAVE_ ## BPP(DEST); \
|
||||
|
||||
#define NORMAL_DW(BPP,FROM,DEST) \
|
||||
MAKE_ ## BPP (FROM); \
|
||||
SAVE_ ## BPP (DEST); \
|
||||
SAVE_ ## BPP (DEST + SIZE_ ## BPP); \
|
||||
|
||||
#define NORMAL_DH(BPP,FROM,DEST) \
|
||||
MAKE_ ## BPP (FROM); \
|
||||
SAVE_ ## BPP (DEST); \
|
||||
SAVE_ ## BPP ((DEST) + render.op.pitch); \
|
||||
|
||||
|
||||
#define NORMAL_DB(BPP,FROM,DEST) \
|
||||
MAKE_ ## BPP (FROM); \
|
||||
SAVE_ ## BPP (DEST); \
|
||||
SAVE_ ## BPP ((DEST)+SIZE_ ## BPP ); \
|
||||
SAVE_ ## BPP ((DEST)+render.op.pitch ); \
|
||||
SAVE_ ## BPP ((DEST)+render.op.pitch+SIZE_ ## BPP ); \
|
||||
|
||||
|
||||
#define NORMAL_LOOP(COUNT,FUNC,BPP) \
|
||||
if (COUNT>0) {NORMAL_ ## FUNC (BPP,(src+0),(dest+0 * PIXELS_ ## FUNC * SIZE_ ## BPP )) }\
|
||||
if (COUNT>1) {NORMAL_ ## FUNC (BPP,(src+1),(dest+1 * PIXELS_ ## FUNC * SIZE_ ## BPP )) }\
|
||||
if (COUNT>2) {NORMAL_ ## FUNC (BPP,(src+2),(dest+2 * PIXELS_ ## FUNC * SIZE_ ## BPP )) }\
|
||||
if (COUNT>3) {NORMAL_ ## FUNC (BPP,(src+3),(dest+3 * PIXELS_ ## FUNC * SIZE_ ## BPP )) }\
|
||||
if (COUNT>4) {NORMAL_ ## FUNC (BPP,(src+4),(dest+4 * PIXELS_ ## FUNC * SIZE_ ## BPP )) }\
|
||||
if (COUNT>5) {NORMAL_ ## FUNC (BPP,(src+5),(dest+5 * PIXELS_ ## FUNC * SIZE_ ## BPP )) }\
|
||||
if (COUNT>6) {NORMAL_ ## FUNC (BPP,(src+6),(dest+6 * PIXELS_ ## FUNC * SIZE_ ## BPP )) }\
|
||||
if (COUNT>7) {NORMAL_ ## FUNC (BPP,(src+7),(dest+7 * PIXELS_ ## FUNC * SIZE_ ## BPP )) }\
|
||||
|
||||
#define MAKENORMAL(FUNC,BPP) \
|
||||
static void Normal_ ## FUNC ## _ ##BPP(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) { \
|
||||
Bit8u * dest=(Bit8u *)render.op.pixels+y*LINES_ ## FUNC*render.op.pitch+x*PIXELS_ ## FUNC * SIZE_ ## BPP; \
|
||||
Bitu next_src=render.src.pitch-dx; \
|
||||
Bitu next_dest=(LINES_ ## FUNC*render.op.pitch) - (dx*PIXELS_ ## FUNC * SIZE_ ## BPP); \
|
||||
dx/=LOOPSIZE; \
|
||||
dy--; \
|
||||
for (;dy>0;dy--) { \
|
||||
for (Bitu tempx=dx;tempx>0;tempx--) { \
|
||||
NORMAL_LOOP(LOOPSIZE,FUNC,BPP); \
|
||||
src+=LOOPSIZE;dest+=LOOPSIZE*PIXELS_ ## FUNC * SIZE_ ## BPP; \
|
||||
} \
|
||||
src+=next_src;dest+=next_dest; \
|
||||
} \
|
||||
}
|
||||
|
||||
MAKENORMAL(DW,8);
|
||||
MAKENORMAL(DB,8);
|
||||
|
||||
MAKENORMAL(DN,16);
|
||||
MAKENORMAL(DW,16);
|
||||
MAKENORMAL(DH,16);
|
||||
MAKENORMAL(DB,16);
|
||||
|
||||
MAKENORMAL(DN,32);
|
||||
MAKENORMAL(DW,32);
|
||||
MAKENORMAL(DH,32);
|
||||
MAKENORMAL(DB,32);
|
||||
|
||||
/* Special versions for the 8-bit ones that can do direct line copying */
|
||||
|
||||
static void Normal_DN_8(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) {
|
||||
Bit8u * dest=(Bit8u *)render.op.pixels+y*render.op.pitch+x;
|
||||
Bitu next_src=render.src.pitch-dx;
|
||||
Bitu next_dest=render.op.pitch-dx;
|
||||
Bitu rem=dx&3;dx>>=2;
|
||||
for (;dy>0;dy--) {
|
||||
Bitu tempx;
|
||||
for (tempx=dx;tempx>0;tempx--) {
|
||||
Bit32u temp=*(Bit32u *)src;src+=4;
|
||||
*(Bit32u *)dest=temp;
|
||||
dest+=4;
|
||||
}
|
||||
for (tempx=rem;tempx>0;tempx--) {
|
||||
*dest++=*src++;
|
||||
}
|
||||
src+=next_src;dest+=next_dest;
|
||||
}
|
||||
}
|
||||
|
||||
static void Normal_DH_8(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) {
|
||||
Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch+x;
|
||||
Bitu next_src=render.src.pitch-dx;
|
||||
Bitu next_dest=(2*render.op.pitch)-dx;
|
||||
Bitu rem=dx&3;dx>>=2;
|
||||
for (;dy>0;dy--) {
|
||||
Bitu tempx;
|
||||
for (tempx=dx;tempx>0;tempx--) {
|
||||
Bit32u temp=*(Bit32u *)src;src+=4;
|
||||
*(Bit32u *)dest=temp;
|
||||
*(Bit32u *)(dest+render.op.pitch)=temp;
|
||||
dest+=4;
|
||||
}
|
||||
for (tempx=rem;tempx>0;tempx--) {
|
||||
*dest=*src;
|
||||
*(dest+render.op.pitch)=*src;
|
||||
dest++;
|
||||
}
|
||||
src+=next_src;dest+=next_dest;
|
||||
}
|
||||
}
|
||||
|
||||
static RENDER_Part_Handler Render_Normal_8_Table[4]= {
|
||||
Normal_DN_8,Normal_DW_8,Normal_DH_8,Normal_DB_8,
|
||||
};
|
||||
|
||||
static RENDER_Part_Handler Render_Normal_16_Table[4]= {
|
||||
Normal_DN_16,Normal_DW_16,Normal_DH_16,Normal_DB_16,
|
||||
};
|
||||
|
||||
static RENDER_Part_Handler Render_Normal_32_Table[4]= {
|
||||
Normal_DN_32,Normal_DW_32,Normal_DH_32,Normal_DB_32,
|
||||
};
|
||||
|
||||
static void Render_Normal_CallBack(Bitu width,Bitu height,Bitu bpp,Bitu pitch,Bitu flags) {
|
||||
if (!(flags & MODE_SET)) return;
|
||||
render.op.width=width;
|
||||
render.op.height=height;
|
||||
render.op.bpp=bpp;
|
||||
render.op.pitch=pitch;
|
||||
render.op.type=OP_None;
|
||||
switch (bpp) {
|
||||
case 8:
|
||||
render.op.part_handler=Render_Normal_8_Table[render.src.flags];
|
||||
break;
|
||||
case 16:
|
||||
render.op.part_handler=Render_Normal_16_Table[render.src.flags];
|
||||
break;
|
||||
case 32:
|
||||
render.op.part_handler=Render_Normal_32_Table[render.src.flags];
|
||||
break;
|
||||
default:
|
||||
E_Exit("RENDER:Unsupported display depth of %d",bpp);
|
||||
break;
|
||||
}
|
||||
RENDER_ResetPal();
|
||||
}
|
562
src/gui/render_scale2x.h
Normal file
562
src/gui/render_scale2x.h
Normal file
@ -0,0 +1,562 @@
|
||||
/*
|
||||
* This file is part of the Scale2x project.
|
||||
*
|
||||
* Copyright (C) 2001-2002 Andrea Mazzoleni
|
||||
*
|
||||
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* In addition, as a special exception, Andrea Mazzoleni
|
||||
* gives permission to link the code of this program with
|
||||
* the MAME library (or with modified versions of MAME that use the
|
||||
* same license as MAME), and distribute linked combinations including
|
||||
* the two. You must obey the GNU General Public License in all
|
||||
* respects for all of the code used other than MAME. If you modify
|
||||
* this file, you may extend this exception to your version of the
|
||||
* file, but you are not obligated to do so. If you do not wish to
|
||||
* do so, delete this exception statement from your version.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file contains a C and MMX implentation of the Scale2x effect.
|
||||
*
|
||||
* You can found an high level description of the effect at :
|
||||
*
|
||||
* http://scale2x.sourceforge.net/scale2x.html
|
||||
*
|
||||
* Alternatively at the previous license terms, you are allowed to use this
|
||||
* code in your program with these conditions:
|
||||
* - the program is not used in commercial activities.
|
||||
* - the whole source code of the program is released with the binary.
|
||||
* - derivative works of the program are allowed.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Made some changes to only support the 8-bit version.
|
||||
* Also added mulitple destination bpp targets.
|
||||
*/
|
||||
|
||||
#ifndef __SCALE2X_H
|
||||
#define __SCALE2X_H
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
/***************************************************************************/
|
||||
/* basic types */
|
||||
|
||||
typedef Bit8u scale2x_uint8;
|
||||
typedef Bit16u scale2x_uint16;
|
||||
typedef Bit32u scale2x_uint32;
|
||||
|
||||
#if !defined(__GNUC__) || !defined(__i386__)
|
||||
|
||||
#define SCALE2X_NORMAL 1
|
||||
|
||||
static void scale2x_line_8(scale2x_uint8* dst0, scale2x_uint8* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count)
|
||||
{
|
||||
assert(count >= 2);
|
||||
|
||||
/* first pixel */
|
||||
dst0[0] = src1[0];
|
||||
dst1[0] = src1[0];
|
||||
if (src1[1] == src0[0] && src2[0] != src0[0])
|
||||
dst0[1] = src0[0];
|
||||
else
|
||||
dst0[1] = src1[0];
|
||||
if (src1[1] == src2[0] && src0[0] != src2[0])
|
||||
dst1[1] = src2[0];
|
||||
else
|
||||
dst1[1] = src1[0];
|
||||
++src0;
|
||||
++src1;
|
||||
++src2;
|
||||
dst0 += 2;
|
||||
dst1 += 2;
|
||||
|
||||
/* central pixels */
|
||||
count -= 2;
|
||||
while (count) {
|
||||
if (src1[-1] == src0[0] && src2[0] != src0[0] && src1[1] != src0[0])
|
||||
dst0[0] = src0[0];
|
||||
else
|
||||
dst0[0] = src1[0];
|
||||
if (src1[1] == src0[0] && src2[0] != src0[0] && src1[-1] != src0[0])
|
||||
dst0[1] = src0[0];
|
||||
else
|
||||
dst0[1] = src1[0];
|
||||
|
||||
if (src1[-1] == src2[0] && src0[0] != src2[0] && src1[1] != src2[0])
|
||||
dst1[0] = src2[0];
|
||||
else
|
||||
dst1[0] = src1[0];
|
||||
if (src1[1] == src2[0] && src0[0] != src2[0] && src1[-1] != src2[0])
|
||||
dst1[1] = src2[0];
|
||||
else
|
||||
dst1[1] = src1[0];
|
||||
|
||||
++src0;
|
||||
++src1;
|
||||
++src2;
|
||||
dst0 += 2;
|
||||
dst1 += 2;
|
||||
--count;
|
||||
}
|
||||
|
||||
/* last pixel */
|
||||
if (src1[-1] == src0[0] && src2[0] != src0[0])
|
||||
dst0[0] = src0[0];
|
||||
else
|
||||
dst0[0] = src1[0];
|
||||
if (src1[-1] == src2[0] && src0[0] != src2[0])
|
||||
dst1[0] = src2[0];
|
||||
else
|
||||
dst1[0] = src1[0];
|
||||
dst0[1] = src1[0];
|
||||
dst1[1] = src1[0];
|
||||
}
|
||||
|
||||
static void scale2x_line_16(scale2x_uint16* dst0, scale2x_uint16* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count)
|
||||
{
|
||||
assert(count >= 2);
|
||||
|
||||
/* first pixel */
|
||||
dst0[0] = render.pal.lookup.bpp16[src1[0]];
|
||||
dst1[0] = render.pal.lookup.bpp16[src1[0]];
|
||||
if (src1[1] == src0[0] && src2[0] != src0[0])
|
||||
dst0[1] = render.pal.lookup.bpp16[src0[0]];
|
||||
else
|
||||
dst0[1] = render.pal.lookup.bpp16[src1[0]];
|
||||
if (src1[1] == src2[0] && src0[0] != src2[0])
|
||||
dst1[1] = render.pal.lookup.bpp16[src2[0]];
|
||||
else
|
||||
dst1[1] = render.pal.lookup.bpp16[src1[0]];
|
||||
++src0;
|
||||
++src1;
|
||||
++src2;
|
||||
dst0 += 2;
|
||||
dst1 += 2;
|
||||
|
||||
/* central pixels */
|
||||
count -= 2;
|
||||
while (count) {
|
||||
if (src1[-1] == src0[0] && src2[0] != src0[0] && src1[1] != src0[0])
|
||||
dst0[0] = render.pal.lookup.bpp16[src0[0]];
|
||||
else
|
||||
dst0[0] = render.pal.lookup.bpp16[src1[0]];
|
||||
if (src1[1] == src0[0] && src2[0] != src0[0] && src1[-1] != src0[0])
|
||||
dst0[1] = render.pal.lookup.bpp16[src0[0]];
|
||||
else
|
||||
dst0[1] = render.pal.lookup.bpp16[src1[0]];
|
||||
|
||||
if (src1[-1] == src2[0] && src0[0] != src2[0] && src1[1] != src2[0])
|
||||
dst1[0] = render.pal.lookup.bpp16[src2[0]];
|
||||
else
|
||||
dst1[0] = render.pal.lookup.bpp16[src1[0]];
|
||||
if (src1[1] == src2[0] && src0[0] != src2[0] && src1[-1] != src2[0])
|
||||
dst1[1] = render.pal.lookup.bpp16[src2[0]];
|
||||
else
|
||||
dst1[1] = render.pal.lookup.bpp16[src1[0]];
|
||||
|
||||
++src0;
|
||||
++src1;
|
||||
++src2;
|
||||
dst0 += 2;
|
||||
dst1 += 2;
|
||||
--count;
|
||||
}
|
||||
|
||||
/* last pixel */
|
||||
if (src1[-1] == src0[0] && src2[0] != src0[0])
|
||||
dst0[0] = render.pal.lookup.bpp16[src0[0]];
|
||||
else
|
||||
dst0[0] = render.pal.lookup.bpp16[src1[0]];
|
||||
if (src1[-1] == src2[0] && src0[0] != src2[0])
|
||||
dst1[0] = render.pal.lookup.bpp16[src2[0]];
|
||||
else
|
||||
dst1[0] = render.pal.lookup.bpp16[src1[0]];
|
||||
dst0[1] = render.pal.lookup.bpp16[src1[0]];
|
||||
dst1[1] = render.pal.lookup.bpp16[src1[0]];
|
||||
}
|
||||
|
||||
static void scale2x_line_32(scale2x_uint32* dst0, scale2x_uint32* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count)
|
||||
{
|
||||
assert(count >= 2);
|
||||
|
||||
/* first pixel */
|
||||
dst0[0] = render.pal.lookup.bpp32[src1[0]];
|
||||
dst1[0] = render.pal.lookup.bpp32[src1[0]];
|
||||
if (src1[1] == src0[0] && src2[0] != src0[0])
|
||||
dst0[1] = render.pal.lookup.bpp32[src0[0]];
|
||||
else
|
||||
dst0[1] = render.pal.lookup.bpp32[src1[0]];
|
||||
if (src1[1] == src2[0] && src0[0] != src2[0])
|
||||
dst1[1] = render.pal.lookup.bpp32[src2[0]];
|
||||
else
|
||||
dst1[1] = render.pal.lookup.bpp32[src1[0]];
|
||||
++src0;
|
||||
++src1;
|
||||
++src2;
|
||||
dst0 += 2;
|
||||
dst1 += 2;
|
||||
|
||||
/* central pixels */
|
||||
count -= 2;
|
||||
while (count) {
|
||||
if (src1[-1] == src0[0] && src2[0] != src0[0] && src1[1] != src0[0])
|
||||
dst0[0] = render.pal.lookup.bpp32[src0[0]];
|
||||
else
|
||||
dst0[0] = render.pal.lookup.bpp32[src1[0]];
|
||||
if (src1[1] == src0[0] && src2[0] != src0[0] && src1[-1] != src0[0])
|
||||
dst0[1] = render.pal.lookup.bpp32[src0[0]];
|
||||
else
|
||||
dst0[1] = render.pal.lookup.bpp32[src1[0]];
|
||||
|
||||
if (src1[-1] == src2[0] && src0[0] != src2[0] && src1[1] != src2[0])
|
||||
dst1[0] = render.pal.lookup.bpp32[src2[0]];
|
||||
else
|
||||
dst1[0] = render.pal.lookup.bpp32[src1[0]];
|
||||
if (src1[1] == src2[0] && src0[0] != src2[0] && src1[-1] != src2[0])
|
||||
dst1[1] = render.pal.lookup.bpp32[src2[0]];
|
||||
else
|
||||
dst1[1] = render.pal.lookup.bpp32[src1[0]];
|
||||
|
||||
++src0;
|
||||
++src1;
|
||||
++src2;
|
||||
dst0 += 2;
|
||||
dst1 += 2;
|
||||
--count;
|
||||
}
|
||||
|
||||
/* last pixel */
|
||||
if (src1[-1] == src0[0] && src2[0] != src0[0])
|
||||
dst0[0] = render.pal.lookup.bpp32[src0[0]];
|
||||
else
|
||||
dst0[0] = render.pal.lookup.bpp32[src1[0]];
|
||||
if (src1[-1] == src2[0] && src0[0] != src2[0])
|
||||
dst1[0] = render.pal.lookup.bpp32[src2[0]];
|
||||
else
|
||||
dst1[0] = render.pal.lookup.bpp32[src1[0]];
|
||||
dst0[1] = render.pal.lookup.bpp32[src1[0]];
|
||||
dst1[1] = render.pal.lookup.bpp32[src1[0]];
|
||||
}
|
||||
|
||||
static void Scale2x_8(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) {
|
||||
if (dy<3) return;
|
||||
Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch;
|
||||
/* First line */
|
||||
scale2x_line_8(dest,dest+render.op.pitch,src,src,src+render.src.pitch,dx);
|
||||
dest+=render.op.pitch*2;
|
||||
src+=render.src.pitch;
|
||||
dy-=2;
|
||||
/* Middle part */
|
||||
for (;dy>0;dy--) {
|
||||
scale2x_line_8((Bit8u *)dest,(Bit8u *)(dest+render.op.pitch),src-render.src.pitch,src,src+render.src.pitch,dx);
|
||||
dest+=render.op.pitch*2;
|
||||
src+=render.src.pitch;
|
||||
}
|
||||
/* Last Line */
|
||||
scale2x_line_8((Bit8u *)dest,(Bit8u *)(dest+render.op.pitch),src-render.src.pitch,src,src,dx);
|
||||
}
|
||||
|
||||
static void Scale2x_16(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) {
|
||||
if (dy<3) return;
|
||||
Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch;
|
||||
/* First line */
|
||||
scale2x_line_16((Bit16u *)dest,(Bit16u *)(dest+render.op.pitch),src,src,src+render.src.pitch,dx);
|
||||
dest+=render.op.pitch*2;
|
||||
src+=render.src.pitch;
|
||||
dy-=2;
|
||||
/* Middle part */
|
||||
for (;dy>0;dy--) {
|
||||
scale2x_line_16((Bit16u *)dest,(Bit16u *)(dest+render.op.pitch),src-render.src.pitch,src,src+render.src.pitch,dx);
|
||||
dest+=render.op.pitch*2;
|
||||
src+=render.src.pitch;
|
||||
}
|
||||
/* Last Line */
|
||||
scale2x_line_16((Bit16u *)dest,(Bit16u *)(dest+render.op.pitch),src-render.src.pitch,src,src,dx);
|
||||
}
|
||||
|
||||
static void Scale2x_32(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) {
|
||||
if (dy<3) return;
|
||||
Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch;
|
||||
/* First line */
|
||||
scale2x_line_32((Bit32u *)dest,(Bit32u *)(dest+render.op.pitch),src,src,src+render.src.pitch,dx);
|
||||
dest+=render.op.pitch*2;
|
||||
src+=render.src.pitch;
|
||||
dy-=2;
|
||||
/* Middle part */
|
||||
for (;dy>0;dy--) {
|
||||
scale2x_line_32((Bit32u *)dest,(Bit32u *)(dest+render.op.pitch),src-render.src.pitch,src,src+render.src.pitch,dx);
|
||||
dest+=render.op.pitch*2;
|
||||
src+=render.src.pitch;
|
||||
}
|
||||
/* Last Line */
|
||||
scale2x_line_32((Bit32u *)dest,(Bit32u *)(dest+render.op.pitch),src-render.src.pitch,src,src,dx);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define SCALE2X_MMX 1
|
||||
|
||||
static __inline__ void scale2x_8_mmx_single(scale2x_uint8* dst, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count)
|
||||
{
|
||||
assert(count >= 16);
|
||||
assert(count % 8 == 0);
|
||||
|
||||
/* always do the first and last run */
|
||||
count -= 2*8;
|
||||
|
||||
__asm__ __volatile__(
|
||||
/* first run */
|
||||
/* set the current, current_pre, current_next registers */
|
||||
"movq 0(%1),%%mm0\n"
|
||||
"movq 0(%1),%%mm7\n"
|
||||
"movq 8(%1),%%mm1\n"
|
||||
"psllq $56,%%mm0\n"
|
||||
"psllq $56,%%mm1\n"
|
||||
"psrlq $56,%%mm0\n"
|
||||
"movq %%mm7,%%mm2\n"
|
||||
"movq %%mm7,%%mm3\n"
|
||||
"psllq $8,%%mm2\n"
|
||||
"psrlq $8,%%mm3\n"
|
||||
"por %%mm2,%%mm0\n"
|
||||
"por %%mm3,%%mm1\n"
|
||||
|
||||
/* current_upper */
|
||||
"movq (%0),%%mm6\n"
|
||||
|
||||
/* compute the upper-left pixel for dst on %%mm2 */
|
||||
/* compute the upper-right pixel for dst on %%mm4 */
|
||||
"movq %%mm0,%%mm2\n"
|
||||
"movq %%mm1,%%mm4\n"
|
||||
"movq %%mm0,%%mm3\n"
|
||||
"movq %%mm1,%%mm5\n"
|
||||
"pcmpeqb %%mm6,%%mm2\n"
|
||||
"pcmpeqb %%mm6,%%mm4\n"
|
||||
"pcmpeqb (%2),%%mm3\n"
|
||||
"pcmpeqb (%2),%%mm5\n"
|
||||
"pandn %%mm2,%%mm3\n"
|
||||
"pandn %%mm4,%%mm5\n"
|
||||
"movq %%mm0,%%mm2\n"
|
||||
"movq %%mm1,%%mm4\n"
|
||||
"pcmpeqb %%mm1,%%mm2\n"
|
||||
"pcmpeqb %%mm0,%%mm4\n"
|
||||
"pandn %%mm3,%%mm2\n"
|
||||
"pandn %%mm5,%%mm4\n"
|
||||
"movq %%mm2,%%mm3\n"
|
||||
"movq %%mm4,%%mm5\n"
|
||||
"pand %%mm6,%%mm2\n"
|
||||
"pand %%mm6,%%mm4\n"
|
||||
"pandn %%mm7,%%mm3\n"
|
||||
"pandn %%mm7,%%mm5\n"
|
||||
"por %%mm3,%%mm2\n"
|
||||
"por %%mm5,%%mm4\n"
|
||||
|
||||
/* set *dst */
|
||||
"movq %%mm2,%%mm3\n"
|
||||
"punpcklbw %%mm4,%%mm2\n"
|
||||
"punpckhbw %%mm4,%%mm3\n"
|
||||
"movq %%mm2,(%3)\n"
|
||||
"movq %%mm3,8(%3)\n"
|
||||
|
||||
/* next */
|
||||
"addl $8,%0\n"
|
||||
"addl $8,%1\n"
|
||||
"addl $8,%2\n"
|
||||
"addl $16,%3\n"
|
||||
|
||||
/* central runs */
|
||||
"shrl $3,%4\n"
|
||||
"jz 1f\n"
|
||||
|
||||
"0:\n"
|
||||
|
||||
/* set the current, current_pre, current_next registers */
|
||||
"movq -8(%1),%%mm0\n"
|
||||
"movq (%1),%%mm7\n"
|
||||
"movq 8(%1),%%mm1\n"
|
||||
"psrlq $56,%%mm0\n"
|
||||
"psllq $56,%%mm1\n"
|
||||
"movq %%mm7,%%mm2\n"
|
||||
"movq %%mm7,%%mm3\n"
|
||||
"psllq $8,%%mm2\n"
|
||||
"psrlq $8,%%mm3\n"
|
||||
"por %%mm2,%%mm0\n"
|
||||
"por %%mm3,%%mm1\n"
|
||||
|
||||
/* current_upper */
|
||||
"movq (%0),%%mm6\n"
|
||||
|
||||
/* compute the upper-left pixel for dst on %%mm2 */
|
||||
/* compute the upper-right pixel for dst on %%mm4 */
|
||||
"movq %%mm0,%%mm2\n"
|
||||
"movq %%mm1,%%mm4\n"
|
||||
"movq %%mm0,%%mm3\n"
|
||||
"movq %%mm1,%%mm5\n"
|
||||
"pcmpeqb %%mm6,%%mm2\n"
|
||||
"pcmpeqb %%mm6,%%mm4\n"
|
||||
"pcmpeqb (%2),%%mm3\n"
|
||||
"pcmpeqb (%2),%%mm5\n"
|
||||
"pandn %%mm2,%%mm3\n"
|
||||
"pandn %%mm4,%%mm5\n"
|
||||
"movq %%mm0,%%mm2\n"
|
||||
"movq %%mm1,%%mm4\n"
|
||||
"pcmpeqb %%mm1,%%mm2\n"
|
||||
"pcmpeqb %%mm0,%%mm4\n"
|
||||
"pandn %%mm3,%%mm2\n"
|
||||
"pandn %%mm5,%%mm4\n"
|
||||
"movq %%mm2,%%mm3\n"
|
||||
"movq %%mm4,%%mm5\n"
|
||||
"pand %%mm6,%%mm2\n"
|
||||
"pand %%mm6,%%mm4\n"
|
||||
"pandn %%mm7,%%mm3\n"
|
||||
"pandn %%mm7,%%mm5\n"
|
||||
"por %%mm3,%%mm2\n"
|
||||
"por %%mm5,%%mm4\n"
|
||||
|
||||
/* set *dst */
|
||||
"movq %%mm2,%%mm3\n"
|
||||
"punpcklbw %%mm4,%%mm2\n"
|
||||
"punpckhbw %%mm4,%%mm3\n"
|
||||
"movq %%mm2,(%3)\n"
|
||||
"movq %%mm3,8(%3)\n"
|
||||
|
||||
/* next */
|
||||
"addl $8,%0\n"
|
||||
"addl $8,%1\n"
|
||||
"addl $8,%2\n"
|
||||
"addl $16,%3\n"
|
||||
|
||||
"decl %4\n"
|
||||
"jnz 0b\n"
|
||||
"1:\n"
|
||||
|
||||
/* final run */
|
||||
/* set the current, current_pre, current_next registers */
|
||||
"movq (%1),%%mm1\n"
|
||||
"movq (%1),%%mm7\n"
|
||||
"movq -8(%1),%%mm0\n"
|
||||
"psrlq $56,%%mm1\n"
|
||||
"psrlq $56,%%mm0\n"
|
||||
"psllq $56,%%mm1\n"
|
||||
"movq %%mm7,%%mm2\n"
|
||||
"movq %%mm7,%%mm3\n"
|
||||
"psllq $8,%%mm2\n"
|
||||
"psrlq $8,%%mm3\n"
|
||||
"por %%mm2,%%mm0\n"
|
||||
"por %%mm3,%%mm1\n"
|
||||
|
||||
/* current_upper */
|
||||
"movq (%0),%%mm6\n"
|
||||
|
||||
/* compute the upper-left pixel for dst on %%mm2 */
|
||||
/* compute the upper-right pixel for dst on %%mm4 */
|
||||
"movq %%mm0,%%mm2\n"
|
||||
"movq %%mm1,%%mm4\n"
|
||||
"movq %%mm0,%%mm3\n"
|
||||
"movq %%mm1,%%mm5\n"
|
||||
"pcmpeqb %%mm6,%%mm2\n"
|
||||
"pcmpeqb %%mm6,%%mm4\n"
|
||||
"pcmpeqb (%2),%%mm3\n"
|
||||
"pcmpeqb (%2),%%mm5\n"
|
||||
"pandn %%mm2,%%mm3\n"
|
||||
"pandn %%mm4,%%mm5\n"
|
||||
"movq %%mm0,%%mm2\n"
|
||||
"movq %%mm1,%%mm4\n"
|
||||
"pcmpeqb %%mm1,%%mm2\n"
|
||||
"pcmpeqb %%mm0,%%mm4\n"
|
||||
"pandn %%mm3,%%mm2\n"
|
||||
"pandn %%mm5,%%mm4\n"
|
||||
"movq %%mm2,%%mm3\n"
|
||||
"movq %%mm4,%%mm5\n"
|
||||
"pand %%mm6,%%mm2\n"
|
||||
"pand %%mm6,%%mm4\n"
|
||||
"pandn %%mm7,%%mm3\n"
|
||||
"pandn %%mm7,%%mm5\n"
|
||||
"por %%mm3,%%mm2\n"
|
||||
"por %%mm5,%%mm4\n"
|
||||
|
||||
/* set *dst */
|
||||
"movq %%mm2,%%mm3\n"
|
||||
"punpcklbw %%mm4,%%mm2\n"
|
||||
"punpckhbw %%mm4,%%mm3\n"
|
||||
"movq %%mm2,(%3)\n"
|
||||
"movq %%mm3,8(%3)\n"
|
||||
|
||||
: "+r" (src0), "+r" (src1), "+r" (src2), "+r" (dst), "+r" (count)
|
||||
:
|
||||
: "cc"
|
||||
);
|
||||
}
|
||||
|
||||
static void scale2x_line_8_mmx(scale2x_uint8* dst0, scale2x_uint8* dst1, const scale2x_uint8* src0, const scale2x_uint8* src1, const scale2x_uint8* src2, unsigned count)
|
||||
{
|
||||
assert(count >= 16);
|
||||
assert(count % 8 == 0);
|
||||
|
||||
scale2x_8_mmx_single(dst0, src0, src1, src2, count);
|
||||
scale2x_8_mmx_single(dst1, src2, src1, src0, count);
|
||||
}
|
||||
|
||||
static void Scale2x_8_mmx(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) {
|
||||
if (dy<3) return;
|
||||
Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch;
|
||||
/* First line */
|
||||
scale2x_line_8_mmx(dest,dest+render.op.pitch,src,src,src+render.src.pitch,dx);
|
||||
dest+=render.op.pitch*2;
|
||||
src+=render.src.pitch;
|
||||
dy-=2;
|
||||
/* Middle part */
|
||||
for (;dy>0;dy--) {
|
||||
scale2x_line_8_mmx((Bit8u *)dest,(Bit8u *)(dest+render.op.pitch),src-render.src.pitch,src,src+render.src.pitch,dx);
|
||||
dest+=render.op.pitch*2;
|
||||
src+=render.src.pitch;
|
||||
}
|
||||
/* Last Line */
|
||||
scale2x_line_8_mmx((Bit8u *)dest,(Bit8u *)(dest+render.op.pitch),src-render.src.pitch,src,src,dx);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void Render_Scale2x_CallBack(Bitu width,Bitu height,Bitu bpp,Bitu pitch,Bitu flags) {
|
||||
if (!(flags & MODE_SET)) return;
|
||||
render.op.width=width;
|
||||
render.op.height=height;
|
||||
render.op.bpp=bpp;
|
||||
render.op.pitch=pitch;
|
||||
render.op.type=OP_Scale2x;
|
||||
#if defined(SCALE2X_NORMAL)
|
||||
switch (bpp) {
|
||||
case 8:
|
||||
render.op.part_handler=Scale2x_8;
|
||||
break;
|
||||
case 16:
|
||||
render.op.part_handler=Scale2x_16;;
|
||||
break;
|
||||
case 32:
|
||||
render.op.part_handler=Scale2x_32;
|
||||
break;
|
||||
default:
|
||||
E_Exit("RENDER:Unsupported display depth of %d",bpp);
|
||||
break;
|
||||
}
|
||||
#elif defined(SCALE2X_MMX)
|
||||
assert (bpp==8);
|
||||
render.op.part_handler=Scale2x_8_mmx;
|
||||
#endif
|
||||
RENDER_ResetPal();
|
||||
}
|
||||
|
||||
#endif
|
@ -1,228 +0,0 @@
|
||||
static void Render_Normal_8_None(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) {
|
||||
Bit8u * dest=(Bit8u *)render.op.pixels+y*render.op.pitch+x;
|
||||
Bitu next_src=render.src.pitch-dx;
|
||||
Bitu next_dest=render.op.pitch-dx;
|
||||
Bitu rem=dx&3;dx>>=2;
|
||||
for (;dy>0;dy--) {
|
||||
Bitu tempx;
|
||||
for (tempx=dx;tempx>0;tempx--) {
|
||||
Bit32u temp=*(Bit32u *)src;src+=4;
|
||||
*(Bit32u *)dest=temp;
|
||||
dest+=4;
|
||||
}
|
||||
for (tempx=rem;tempx>0;tempx--) {
|
||||
*dest++=*src++;
|
||||
}
|
||||
src+=next_src;dest+=next_dest;
|
||||
}
|
||||
}
|
||||
|
||||
static void Render_Normal_8_DoubleWidth(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) {
|
||||
Bit8u * dest=(Bit8u *)render.op.pixels+y*render.op.pitch+x*2;
|
||||
Bitu next_src=render.src.pitch-dx;
|
||||
Bitu next_dest=render.op.pitch-dx*2;
|
||||
for (;dy>0;dy--) {
|
||||
for (Bitu tempx=dx;tempx>0;tempx--) {
|
||||
*dest=*src;*(dest+1)=*src;
|
||||
src++;dest+=2;
|
||||
}
|
||||
src+=next_src;dest+=next_dest;
|
||||
}
|
||||
}
|
||||
|
||||
static void Render_Normal_8_DoubleHeight(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) {
|
||||
Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch+x;
|
||||
Bitu next_src=render.src.pitch-dx;
|
||||
Bitu next_dest=(2*render.op.pitch)-dx;
|
||||
Bitu rem=dx&3;dx>>=2;
|
||||
for (;dy>0;dy--) {
|
||||
Bitu tempx;
|
||||
for (tempx=dx;tempx>0;tempx--) {
|
||||
Bit32u temp=*(Bit32u *)src;src+=4;
|
||||
*(Bit32u *)dest=temp;
|
||||
*(Bit32u *)(dest+render.op.pitch)=temp;
|
||||
dest+=4;
|
||||
}
|
||||
for (tempx=rem;tempx>0;tempx--) {
|
||||
*dest=*src;
|
||||
*(dest+render.op.pitch)=*src;
|
||||
dest++;
|
||||
}
|
||||
src+=next_src;dest+=next_dest;
|
||||
}
|
||||
}
|
||||
|
||||
static void Render_Normal_8_DoubleBoth(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) {
|
||||
Bit8u * dest=(Bit8u *)render.op.pixels+y*render.op.pitch+x;
|
||||
Bitu next_src=render.src.pitch-dx;
|
||||
Bitu next_dest=(2*render.op.pitch)-dx*2;
|
||||
for (;dy>0;dy--) {
|
||||
for (Bitu tempx=dx;tempx>0;tempx--) {
|
||||
Bit8u val=src[0];src++;
|
||||
dest[0]=val;dest[1]=val;
|
||||
dest[render.op.pitch]=val;dest[render.op.pitch+1]=val;
|
||||
dest+=2;
|
||||
}
|
||||
src+=next_src;dest+=next_dest;
|
||||
}
|
||||
}
|
||||
|
||||
static void Render_Normal_16_None(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) {
|
||||
Bit8u * dest=(Bit8u *)render.op.pixels+y*render.op.pitch+x;
|
||||
Bitu next_src=render.src.pitch-dx;
|
||||
Bitu next_dest=render.op.pitch-dx*2;
|
||||
for (;dy>0;dy--) {
|
||||
for (Bitu tempx=dx;tempx>0;tempx--) {
|
||||
Bit16u val=render.pal.lookup.bpp16[src[0]];src++;
|
||||
*(Bit16u *)dest=val;
|
||||
dest+=2;
|
||||
}
|
||||
src+=next_src;dest+=next_dest;
|
||||
}
|
||||
}
|
||||
|
||||
static void Render_Normal_16_DoubleWidth(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) {
|
||||
Bit8u * dest=(Bit8u *)render.op.pixels+y*render.op.pitch+x*4;
|
||||
Bitu next_src=render.src.pitch-dx;
|
||||
Bitu next_dest=render.op.pitch-dx*4;
|
||||
for (;dy>0;dy--) {
|
||||
for (Bitu tempx=dx;tempx>0;tempx--) {
|
||||
Bit16u val=render.pal.lookup.bpp16[src[0]];src++;
|
||||
*(Bit16u *)dest=val;
|
||||
*(Bit16u *)(dest+2)=val;
|
||||
dest+=4;
|
||||
}
|
||||
src+=next_src;dest+=next_dest;
|
||||
}
|
||||
}
|
||||
|
||||
static void Render_Normal_16_DoubleHeight(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) {
|
||||
Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch+x*2;
|
||||
Bitu next_src=render.src.pitch-dx;
|
||||
Bitu next_dest=(2*render.op.pitch)-dx*2;
|
||||
for (;dy>0;dy--) {
|
||||
for (Bitu tempx=dx;tempx>0;tempx--) {
|
||||
Bit16u val=render.pal.lookup.bpp16[src[0]];src++;
|
||||
*(Bit16u *)dest=val;
|
||||
*(Bit16u *)(dest+render.op.pitch)=val;
|
||||
dest+=2;
|
||||
}
|
||||
src+=next_src;dest+=next_dest;
|
||||
}
|
||||
}
|
||||
|
||||
static void Render_Normal_16_DoubleBoth(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) {
|
||||
Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch+x*4;
|
||||
Bitu next_src=render.src.pitch-dx;
|
||||
Bitu next_dest=(2*render.op.pitch)-dx*4;
|
||||
for (;dy>0;dy--) {
|
||||
for (Bitu tempx=dx;tempx>0;tempx--) {
|
||||
Bit16u val=render.pal.lookup.bpp16[src[0]];src++;
|
||||
*(Bit16u *)(dest+0)=val;
|
||||
*(Bit16u *)(dest+2)=val;
|
||||
*(Bit16u *)(dest+render.op.pitch)=val;
|
||||
*(Bit16u *)(dest+render.op.pitch+2)=val;
|
||||
dest+=4;
|
||||
}
|
||||
src+=next_src;dest+=next_dest;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void Render_Normal_32_None(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) {
|
||||
Bit8u * dest=(Bit8u *)render.op.pixels+y*render.op.pitch+x*4;
|
||||
Bitu next_src=render.src.pitch-dx;
|
||||
Bitu next_dest=render.op.pitch-dx*4;
|
||||
for (;dy>0;dy--) {
|
||||
for (Bitu tempx=dx;tempx>0;tempx--) {
|
||||
Bit32u val=render.pal.lookup.bpp32[src[0]];src++;
|
||||
*(Bit32u *)dest=val;
|
||||
dest+=4;
|
||||
}
|
||||
src+=next_src;dest+=next_dest;
|
||||
}
|
||||
}
|
||||
|
||||
static void Render_Normal_32_DoubleWidth(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) {
|
||||
Bit8u * dest=(Bit8u *)render.op.pixels+y*render.op.pitch+x*8;
|
||||
Bitu next_src=render.src.pitch-dx;
|
||||
Bitu next_dest=render.op.pitch-dx*8;
|
||||
for (;dy>0;dy--) {
|
||||
for (Bitu tempx=dx;tempx>0;tempx--) {
|
||||
Bit32u val=render.pal.lookup.bpp32[src[0]];src++;
|
||||
*(Bit32u *)dest=val;
|
||||
*(Bit32u *)(dest+4)=val;
|
||||
dest+=8;
|
||||
}
|
||||
src+=next_src;dest+=next_dest;
|
||||
}
|
||||
}
|
||||
|
||||
static void Render_Normal_32_DoubleHeight(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) {
|
||||
Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch+x*4;
|
||||
Bitu next_src=render.src.pitch-dx;
|
||||
Bitu next_dest=(2*render.op.pitch)-dx*4;
|
||||
for (;dy>0;dy--) {
|
||||
for (Bitu tempx=dx;tempx>0;tempx--) {
|
||||
Bit32u val=render.pal.lookup.bpp32[src[0]];src++;
|
||||
*(Bit32u *)dest=val;
|
||||
*(Bit32u *)(dest+render.op.pitch)=val;
|
||||
dest+=4;
|
||||
}
|
||||
src+=next_src;dest+=next_dest;
|
||||
}
|
||||
}
|
||||
|
||||
static void Render_Normal_32_DoubleBoth(Bit8u * src,Bitu x,Bitu y,Bitu dx,Bitu dy) {
|
||||
Bit8u * dest=(Bit8u *)render.op.pixels+2*y*render.op.pitch+x*8;
|
||||
Bitu next_src=render.src.pitch-dx;
|
||||
Bitu next_dest=(2*render.op.pitch)-dx*8;
|
||||
for (;dy>0;dy--) {
|
||||
for (Bitu tempx=dx;tempx>0;tempx--) {
|
||||
Bit32u val=render.pal.lookup.bpp32[src[0]];src++;
|
||||
*(Bit32u *)(dest+0)=val;
|
||||
*(Bit32u *)(dest+4)=val;
|
||||
*(Bit32u *)(dest+render.op.pitch)=val;
|
||||
*(Bit32u *)(dest+render.op.pitch+4)=val;
|
||||
dest+=8;
|
||||
}
|
||||
src+=next_src;dest+=next_dest;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static RENDER_Part_Handler Render_Normal_8_Table[4]= {
|
||||
Render_Normal_8_None,Render_Normal_8_DoubleWidth,Render_Normal_8_DoubleHeight,Render_Normal_8_DoubleBoth
|
||||
};
|
||||
|
||||
static RENDER_Part_Handler Render_Normal_16_Table[4]= {
|
||||
Render_Normal_16_None,Render_Normal_16_DoubleWidth,Render_Normal_16_DoubleHeight,Render_Normal_16_DoubleBoth
|
||||
};
|
||||
|
||||
static RENDER_Part_Handler Render_Normal_32_Table[4]= {
|
||||
Render_Normal_32_None,Render_Normal_32_DoubleWidth,Render_Normal_32_DoubleHeight,Render_Normal_32_DoubleBoth
|
||||
};
|
||||
|
||||
|
||||
static void Render_Normal_CallBack(Bitu width,Bitu height,Bitu bpp,Bitu pitch,Bitu flags) {
|
||||
if (!(flags & MODE_SET)) return;
|
||||
render.op.width=width;
|
||||
render.op.height=height;
|
||||
render.op.bpp=bpp;
|
||||
render.op.pitch=pitch;
|
||||
switch (bpp) {
|
||||
case 8:
|
||||
render.src.part_handler=Render_Normal_8_Table[render.src.flags];
|
||||
break;
|
||||
case 16:
|
||||
render.src.part_handler=Render_Normal_16_Table[render.src.flags];
|
||||
break;
|
||||
case 32:
|
||||
render.src.part_handler=Render_Normal_32_Table[render.src.flags];
|
||||
break;
|
||||
default:
|
||||
E_Exit("RENDER:Unsupported display depth of %d",bpp);
|
||||
break;
|
||||
}
|
||||
RENDER_ResetPal();
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2002 The DOSBox Team
|
||||
* Copyright (C) 2002-2003 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -15,10 +15,16 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <SDL.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "SDL.h"
|
||||
#include "SDL_thread.h"
|
||||
|
||||
#include "dosbox.h"
|
||||
#include "video.h"
|
||||
@ -31,17 +37,33 @@
|
||||
#include "debug.h"
|
||||
|
||||
//#define DISABLE_JOYSTICK
|
||||
#define C_GFXTHREADED 1 //Enabled by default
|
||||
|
||||
#if defined(MACOSX)
|
||||
extern char** environ;
|
||||
#endif
|
||||
|
||||
struct SDL_Block {
|
||||
bool active; //If this isn't set don't draw
|
||||
volatile bool active; //If this isn't set don't draw
|
||||
volatile bool drawing;
|
||||
Bitu width;
|
||||
Bitu height;
|
||||
Bitu bpp;
|
||||
Bitu flags;
|
||||
GFX_ModeCallBack mode_callback;
|
||||
bool full_screen;
|
||||
bool nowait;
|
||||
SDL_Surface * surface;
|
||||
SDL_Surface * shadow_surface;
|
||||
SDL_Joystick * joy;
|
||||
SDL_cond *cond;
|
||||
#if C_GFXTHREADED
|
||||
SDL_mutex *mutex;
|
||||
SDL_Thread *thread;
|
||||
SDL_sem *sem;
|
||||
volatile bool kill_thread;
|
||||
#endif
|
||||
GFX_DrawCallBack draw_callback;
|
||||
struct {
|
||||
bool autolock;
|
||||
bool autoenable;
|
||||
@ -58,17 +80,22 @@ static void CaptureMouse(void);
|
||||
static void ResetScreen(void) {
|
||||
GFX_Stop();
|
||||
if (sdl.full_screen) {
|
||||
/* First get the original resolution */
|
||||
sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,sdl.bpp,SDL_HWSURFACE|SDL_HWPALETTE|SDL_FULLSCREEN);
|
||||
if (sdl.flags & GFX_SHADOW) {
|
||||
/* TODO Maybe allocate a shadow surface and blit yourself and do real double buffering too */
|
||||
sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,sdl.bpp,SDL_SWSURFACE|SDL_FULLSCREEN);
|
||||
} else {
|
||||
sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,sdl.bpp,SDL_HWSURFACE|SDL_HWPALETTE|SDL_FULLSCREEN|SDL_DOUBLEBUF);
|
||||
}
|
||||
} else {
|
||||
if (sdl.flags & GFX_FIXED_BPP) sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,sdl.bpp,SDL_HWSURFACE);
|
||||
else sdl.surface=SDL_SetVideoMode(sdl.width,sdl.height,0,SDL_HWSURFACE);
|
||||
}
|
||||
if (sdl.surface==0) {
|
||||
E_Exit("SDL:Would be nice if I could get a surface.");
|
||||
E_Exit("SDL:Can't get a surface error:%s.",SDL_GetError());
|
||||
}
|
||||
|
||||
SDL_WM_SetCaption(VERSION,VERSION);
|
||||
/* also fill up gfx_info structure */
|
||||
|
||||
Bitu flags=MODE_SET;
|
||||
if (sdl.full_screen) flags|=MODE_FULLSCREEN;
|
||||
if (sdl.mode_callback) sdl.mode_callback(sdl.surface->w,sdl.surface->h,sdl.surface->format->BitsPerPixel,sdl.surface->pitch,flags);
|
||||
@ -76,20 +103,18 @@ static void ResetScreen(void) {
|
||||
}
|
||||
|
||||
|
||||
void GFX_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu flags,GFX_ModeCallBack callback) {
|
||||
void GFX_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu flags,GFX_ModeCallBack mode_callback, GFX_DrawCallBack draw_callback){
|
||||
GFX_Stop();
|
||||
sdl.width=width;
|
||||
sdl.height=height;
|
||||
sdl.bpp=bpp;
|
||||
sdl.flags=flags;
|
||||
sdl.mode_callback=callback;
|
||||
sdl.mode_callback=mode_callback;
|
||||
sdl.draw_callback=draw_callback;
|
||||
ResetScreen();
|
||||
GFX_Start();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static void CaptureMouse(void) {
|
||||
sdl.mouse.locked=!sdl.mouse.locked;
|
||||
if (sdl.mouse.locked) {
|
||||
@ -109,32 +134,63 @@ static void SwitchFullScreen(void) {
|
||||
} else {
|
||||
if (sdl.mouse.locked) CaptureMouse();
|
||||
}
|
||||
|
||||
ResetScreen();
|
||||
}
|
||||
//only prototype existed
|
||||
|
||||
void GFX_SwitchFullScreen(void) {
|
||||
SwitchFullScreen();
|
||||
}
|
||||
|
||||
void * GFX_StartUpdate(void) {
|
||||
if (sdl.active) {
|
||||
if (SDL_MUSTLOCK(sdl.surface)) if (SDL_LockSurface(sdl.surface)) return 0;
|
||||
return sdl.surface->pixels;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
static void SDL_DrawScreen(void) {
|
||||
sdl.drawing=true;
|
||||
if (SDL_MUSTLOCK(sdl.surface)) {
|
||||
if (SDL_LockSurface(sdl.surface)) {
|
||||
sdl.drawing=false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
sdl.draw_callback(sdl.surface->pixels);
|
||||
if (SDL_MUSTLOCK(sdl.surface)) {
|
||||
SDL_UnlockSurface(sdl.surface);
|
||||
}
|
||||
SDL_Flip(sdl.surface);
|
||||
sdl.drawing=false;
|
||||
}
|
||||
|
||||
void GFX_EndUpdate(void) {
|
||||
if (SDL_MUSTLOCK(sdl.surface)) SDL_UnlockSurface(sdl.surface );
|
||||
if (sdl.full_screen) SDL_Flip(sdl.surface);
|
||||
else SDL_UpdateRect(sdl.surface,0,0,0,0);
|
||||
#if C_GFXTHREADED
|
||||
int SDL_DisplayThread(void * data) {
|
||||
while (!SDL_SemWait(sdl.sem)) {
|
||||
if (sdl.kill_thread) return 0;
|
||||
if (!sdl.active) continue;
|
||||
if (sdl.drawing) continue;
|
||||
SDL_mutexP(sdl.mutex);
|
||||
SDL_DrawScreen();
|
||||
SDL_mutexV(sdl.mutex);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void GFX_DoUpdate(void) {
|
||||
if (!sdl.active)
|
||||
return;
|
||||
if (sdl.drawing)return;
|
||||
#if C_GFXTHREADED
|
||||
SDL_SemPost(sdl.sem);
|
||||
#else
|
||||
SDL_DrawScreen();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
void GFX_SetPalette(Bitu start,Bitu count,GFX_PalEntry * entries) {
|
||||
/* I should probably not change the GFX_PalEntry :) */
|
||||
#if C_GFXTHREADED
|
||||
if (SDL_mutexP(sdl.mutex)) {
|
||||
E_Exit("SDL:Can't lock Mutex");
|
||||
};
|
||||
#endif
|
||||
/* I should probably not change the GFX_PalEntry :) */
|
||||
if (sdl.full_screen) {
|
||||
if (!SDL_SetPalette(sdl.surface,SDL_PHYSPAL,(SDL_Color *)entries,start,count)) {
|
||||
E_Exit("SDL:Can't set palette");
|
||||
@ -144,6 +200,11 @@ void GFX_SetPalette(Bitu start,Bitu count,GFX_PalEntry * entries) {
|
||||
E_Exit("SDL:Can't set palette");
|
||||
}
|
||||
}
|
||||
#if C_GFXTHREADED
|
||||
if (SDL_mutexV(sdl.mutex)) {
|
||||
E_Exit("SDL:Can't release Mutex");
|
||||
};
|
||||
#endif
|
||||
}
|
||||
|
||||
Bitu GFX_GetRGB(Bit8u red,Bit8u green,Bit8u blue) {
|
||||
@ -151,9 +212,15 @@ Bitu GFX_GetRGB(Bit8u red,Bit8u green,Bit8u blue) {
|
||||
}
|
||||
|
||||
void GFX_Stop() {
|
||||
#if C_GFXTHREADED
|
||||
SDL_mutexP(sdl.mutex);
|
||||
#endif
|
||||
sdl.active=false;
|
||||
}
|
||||
#if C_GFXTHREADED
|
||||
SDL_mutexV(sdl.mutex);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void GFX_Start() {
|
||||
sdl.active=true;
|
||||
@ -163,6 +230,18 @@ static void GUI_ShutDown(Section * sec) {
|
||||
GFX_Stop();
|
||||
if (sdl.mouse.locked) CaptureMouse();
|
||||
if (sdl.full_screen) SwitchFullScreen();
|
||||
#if C_GFXTHREADED
|
||||
sdl.kill_thread=true;
|
||||
SDL_SemPost(sdl.sem);
|
||||
SDL_WaitThread(sdl.thread,0);
|
||||
SDL_DestroyMutex(sdl.mutex);
|
||||
SDL_DestroySemaphore(sdl.sem);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static void KillSwitch(void){
|
||||
throw 1;
|
||||
}
|
||||
|
||||
static void GUI_StartUp(Section * sec) {
|
||||
@ -171,23 +250,26 @@ static void GUI_StartUp(Section * sec) {
|
||||
Section_prop * section=static_cast<Section_prop *>(sec);
|
||||
sdl.active=false;
|
||||
sdl.full_screen=false;
|
||||
sdl.nowait=section->Get_bool("nowait");
|
||||
sdl.mouse.locked=false;
|
||||
sdl.mouse.requestlock=false;
|
||||
sdl.mouse.autoenable=section->Get_bool("autolock");
|
||||
sdl.mouse.autolock=false;
|
||||
sdl.mouse.sensitivity=section->Get_int("sensitivity");
|
||||
GFX_SetSize(640,400,8,0,0);
|
||||
#if C_GFXTHREADED
|
||||
sdl.kill_thread=false;
|
||||
sdl.mutex=SDL_CreateMutex();
|
||||
sdl.sem=SDL_CreateSemaphore(0);
|
||||
sdl.thread=SDL_CreateThread(&SDL_DisplayThread,0);
|
||||
#endif
|
||||
/* Initialize screen for first time */
|
||||
GFX_SetSize(640,400,8,0,0,0);
|
||||
SDL_EnableKeyRepeat(250,30);
|
||||
|
||||
SDL_EnableUNICODE(1);
|
||||
/* Get some Keybinds */
|
||||
KEYBOARD_AddEvent(KBD_f10,CTRL_PRESSED,CaptureMouse);
|
||||
KEYBOARD_AddEvent(KBD_enter,ALT_PRESSED,SwitchFullScreen);
|
||||
}
|
||||
|
||||
void GFX_ShutDown() {
|
||||
if (sdl.full_screen) SwitchFullScreen();
|
||||
if (sdl.mouse.locked) CaptureMouse();
|
||||
GFX_Stop();
|
||||
KEYBOARD_AddEvent(KBD_f9,KBD_MOD_CTRL,KillSwitch);
|
||||
KEYBOARD_AddEvent(KBD_f10,KBD_MOD_CTRL,CaptureMouse);
|
||||
KEYBOARD_AddEvent(KBD_enter,KBD_MOD_ALT,SwitchFullScreen);
|
||||
}
|
||||
|
||||
void Mouse_AutoLock(bool enable) {
|
||||
@ -197,7 +279,7 @@ void Mouse_AutoLock(bool enable) {
|
||||
}
|
||||
|
||||
static void HandleKey(SDL_KeyboardEvent * key) {
|
||||
Bit32u code;
|
||||
KBD_KEYS code;
|
||||
switch (key->keysym.sym) {
|
||||
case SDLK_1:code=KBD_1;break;
|
||||
case SDLK_2:code=KBD_2;break;
|
||||
@ -253,8 +335,6 @@ static void HandleKey(SDL_KeyboardEvent * key) {
|
||||
case SDLK_F11:code=KBD_f11;break;
|
||||
case SDLK_F12:code=KBD_f12;break;
|
||||
|
||||
// KBD_esc,KBD_tab,KBD_backspace,KBD_enter,KBD_space,
|
||||
|
||||
case SDLK_ESCAPE:code=KBD_esc;break;
|
||||
case SDLK_TAB:code=KBD_tab;break;
|
||||
case SDLK_BACKSPACE:code=KBD_backspace;break;
|
||||
@ -314,13 +394,19 @@ static void HandleKey(SDL_KeyboardEvent * key) {
|
||||
case SDLK_KP_ENTER:code=KBD_kpenter;break;
|
||||
case SDLK_KP_PERIOD:code=KBD_kpperiod;break;
|
||||
|
||||
// case SDLK_:code=key_;break;
|
||||
/* Special Keys */
|
||||
default:
|
||||
//TODO maybe give warning for keypress unknown
|
||||
return;
|
||||
code=KBD_1;
|
||||
LOG(LOG_ERROR|LOG_KEYBOARD,"Unhandled SDL keysym %d",key->keysym.sym);
|
||||
break;
|
||||
}
|
||||
KEYBOARD_AddKey(code,(key->state==SDL_PRESSED));
|
||||
/* Check the modifiers */
|
||||
Bitu mod=
|
||||
((key->keysym.mod & KMOD_CTRL) ? KBD_MOD_CTRL : 0) |
|
||||
((key->keysym.mod & KMOD_ALT) ? KBD_MOD_ALT : 0) |
|
||||
((key->keysym.mod & KMOD_SHIFT) ? KBD_MOD_SHIFT : 0);
|
||||
Bitu ascii=key->keysym.unicode<128 ? key->keysym.unicode : 0;
|
||||
KEYBOARD_AddKey(code,ascii,mod,(key->state==SDL_PRESSED));
|
||||
}
|
||||
|
||||
static void HandleMouseMotion(SDL_MouseMotionEvent * motion) {
|
||||
@ -395,7 +481,10 @@ static void HandleVideoResize(SDL_ResizeEvent * resize) {
|
||||
|
||||
}
|
||||
|
||||
static Bit8u laltstate = SDL_KEYUP;
|
||||
|
||||
void GFX_Events() {
|
||||
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch (event.type) {
|
||||
@ -408,6 +497,9 @@ void GFX_Events() {
|
||||
break;
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_KEYUP:
|
||||
// ignore event lalt+tab
|
||||
if (event.key.keysym.sym==SDLK_LALT) laltstate = event.key.type;
|
||||
if ((event.key.keysym.sym==SDLK_TAB) && (laltstate==SDL_KEYDOWN)) break;
|
||||
HandleKey(&event.key);
|
||||
break;
|
||||
case SDL_MOUSEMOTION:
|
||||
@ -428,7 +520,7 @@ void GFX_Events() {
|
||||
HandleVideoResize(&event.resize);
|
||||
break;
|
||||
case SDL_QUIT:
|
||||
E_Exit("Closed the SDL Window");
|
||||
throw(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -442,17 +534,17 @@ void GFX_ShowMsg(char * msg) {
|
||||
};
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
|
||||
#if C_DEBUG
|
||||
DEBUG_SetupConsole();
|
||||
#endif
|
||||
|
||||
|
||||
try {
|
||||
CommandLine com_line(argc,argv);
|
||||
Config myconf(&com_line);
|
||||
control=&myconf;
|
||||
|
||||
#if C_DEBUG
|
||||
DEBUG_SetupConsole();
|
||||
#endif
|
||||
|
||||
if ( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO|SDL_INIT_TIMER
|
||||
if ( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_CDROM
|
||||
#ifndef DISABLE_JOYSTICK
|
||||
|SDL_INIT_JOYSTICK
|
||||
|
||||
@ -462,7 +554,7 @@ int main(int argc, char* argv[]) {
|
||||
sdl_sec->Add_bool("fullscreen",false);
|
||||
sdl_sec->Add_bool("autolock",true);
|
||||
sdl_sec->Add_int("sensitivity",100);
|
||||
|
||||
sdl_sec->Add_bool("nowait",true);
|
||||
/* Init all the dosbox subsystems */
|
||||
DOSBOX_Init();
|
||||
std::string config_file;
|
||||
@ -473,6 +565,7 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
/* Parse the config file */
|
||||
control->ParseConfigFile(config_file.c_str());
|
||||
control->ParseEnv(environ);
|
||||
/* Init all the sections */
|
||||
control->Init();
|
||||
/* Some extra SDL Functions */
|
||||
@ -494,8 +587,11 @@ int main(int argc, char* argv[]) {
|
||||
if (sdl.full_screen) SwitchFullScreen();
|
||||
if (sdl.mouse.locked) CaptureMouse();
|
||||
LOG_MSG("Exit to error: %sPress enter to continue.",error);
|
||||
fgetc(stdin);
|
||||
if(!sdl.nowait) fgetc(stdin);
|
||||
}
|
||||
GFX_ShutDown();
|
||||
return 0;
|
||||
catch (...){
|
||||
if (sdl.full_screen) SwitchFullScreen();
|
||||
if (sdl.mouse.locked) CaptureMouse();
|
||||
}
|
||||
return 0;
|
||||
};
|
||||
|
@ -8,5 +8,5 @@ libhardware_a_SOURCES = adlib.cpp dma.cpp gameblaster.cpp hardware.cpp iohandler
|
||||
memory.cpp mixer.cpp pcspeaker.cpp pic.cpp sblaster.cpp tandy_sound.cpp timer.cpp \
|
||||
vga.cpp vga.h vga_attr.cpp vga_crtc.cpp vga_dac.cpp vga_draw.cpp vga_fonts.cpp vga_gfx.cpp \
|
||||
vga_memory.cpp vga_misc.cpp vga_seq.cpp font-switch.h ega-switch.h cmos.cpp disney.cpp \
|
||||
gus.cpp
|
||||
gus.cpp mpu401.cpp
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Makefile.in generated by automake 1.6.1 from Makefile.am.
|
||||
# Makefile.in generated by automake 1.6.3 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
|
||||
@ -49,6 +49,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = @program_transform_name@
|
||||
@ -64,6 +65,8 @@ host_triplet = @host@
|
||||
EXEEXT = @EXEEXT@
|
||||
OBJEXT = @OBJEXT@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
ALSA_CFLAGS = @ALSA_CFLAGS@
|
||||
ALSA_LIBS = @ALSA_LIBS@
|
||||
AMTAR = @AMTAR@
|
||||
AWK = @AWK@
|
||||
CC = @CC@
|
||||
@ -91,7 +94,7 @@ libhardware_a_SOURCES = adlib.cpp dma.cpp gameblaster.cpp hardware.cpp iohandler
|
||||
memory.cpp mixer.cpp pcspeaker.cpp pic.cpp sblaster.cpp tandy_sound.cpp timer.cpp \
|
||||
vga.cpp vga.h vga_attr.cpp vga_crtc.cpp vga_dac.cpp vga_draw.cpp vga_fonts.cpp vga_gfx.cpp \
|
||||
vga_memory.cpp vga_misc.cpp vga_seq.cpp font-switch.h ega-switch.h cmos.cpp disney.cpp \
|
||||
gus.cpp
|
||||
gus.cpp mpu401.cpp
|
||||
|
||||
subdir = src/hardware
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
@ -109,7 +112,8 @@ am_libhardware_a_OBJECTS = adlib.$(OBJEXT) dma.$(OBJEXT) \
|
||||
vga.$(OBJEXT) vga_attr.$(OBJEXT) vga_crtc.$(OBJEXT) \
|
||||
vga_dac.$(OBJEXT) vga_draw.$(OBJEXT) vga_fonts.$(OBJEXT) \
|
||||
vga_gfx.$(OBJEXT) vga_memory.$(OBJEXT) vga_misc.$(OBJEXT) \
|
||||
vga_seq.$(OBJEXT) cmos.$(OBJEXT) disney.$(OBJEXT) gus.$(OBJEXT)
|
||||
vga_seq.$(OBJEXT) cmos.$(OBJEXT) disney.$(OBJEXT) gus.$(OBJEXT) \
|
||||
mpu401.$(OBJEXT)
|
||||
libhardware_a_OBJECTS = $(am_libhardware_a_OBJECTS)
|
||||
|
||||
DEFS = @DEFS@
|
||||
@ -125,14 +129,14 @@ am__depfiles_maybe = depfiles
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/hardware.Po ./$(DEPDIR)/iohandler.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/joystick.Po ./$(DEPDIR)/keyboard.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/memory.Po ./$(DEPDIR)/mixer.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/pcspeaker.Po ./$(DEPDIR)/pic.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/sblaster.Po ./$(DEPDIR)/tandy_sound.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/timer.Po ./$(DEPDIR)/vga.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/vga_attr.Po ./$(DEPDIR)/vga_crtc.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/vga_dac.Po ./$(DEPDIR)/vga_draw.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/vga_fonts.Po ./$(DEPDIR)/vga_gfx.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/vga_memory.Po ./$(DEPDIR)/vga_misc.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/vga_seq.Po
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/mpu401.Po ./$(DEPDIR)/pcspeaker.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/pic.Po ./$(DEPDIR)/sblaster.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/tandy_sound.Po ./$(DEPDIR)/timer.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/vga.Po ./$(DEPDIR)/vga_attr.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/vga_crtc.Po ./$(DEPDIR)/vga_dac.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/vga_draw.Po ./$(DEPDIR)/vga_fonts.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/vga_gfx.Po ./$(DEPDIR)/vga_memory.Po \
|
||||
@AMDEP_TRUE@ ./$(DEPDIR)/vga_misc.Po ./$(DEPDIR)/vga_seq.Po
|
||||
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
|
||||
CXXLD = $(CXX)
|
||||
@ -185,6 +189,7 @@ distclean-compile:
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keyboard.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/memory.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mixer.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpu401.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcspeaker.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pic.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sblaster.Po@am__quote@
|
||||
@ -259,7 +264,7 @@ top_distdir = ../..
|
||||
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@for file in $(DISTFILES); do \
|
||||
@list='$(DISTFILES)'; for file in $$list; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
|
||||
@ -304,7 +309,7 @@ mostlyclean-generic:
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]*
|
||||
-rm -f Makefile $(CONFIG_CLEAN_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2002 The DOSBox Team
|
||||
* Copyright (C) 2002-2003 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -52,7 +52,7 @@ static void cmos_checktimer(void) {
|
||||
if (!cmos.timer.div && !cmos.timer.enabled) return;
|
||||
if (cmos.timer.div<=2) cmos.timer.div+=7;
|
||||
cmos.timer.micro=(Bitu) (10000000.0/(32768.0 / (1 << (cmos.timer.div - 1))));
|
||||
LOG_DEBUG("RTC Timer at %f hz",1000000.0/cmos.timer.micro);
|
||||
LOG(LOG_PIT,"RTC Timer at %f hz",1000000.0/cmos.timer.micro);
|
||||
PIC_AddEvent(cmos_timerevent,cmos.timer.micro);
|
||||
}
|
||||
|
||||
@ -77,25 +77,25 @@ static void cmos_writereg(Bit32u port,Bit8u val) {
|
||||
break;
|
||||
case 0x0a: /* Status reg A */
|
||||
cmos.regs[cmos.reg]=val & 0x7f;
|
||||
if (val & 0x70!=0x20) LOG_DEBUG("CMOS Illegal 22 stage divider value");
|
||||
if (val & 0x70!=0x20) LOG(LOG_ERROR|LOG_BIOS,"CMOS Illegal 22 stage divider value");
|
||||
cmos.timer.div=(val & 0xf);
|
||||
cmos_checktimer();
|
||||
break;
|
||||
case 0x0b: /* Status reg B */
|
||||
cmos.regs[cmos.reg]=val & 0x7f;
|
||||
cmos.timer.enabled=(val & 0x40)>0;
|
||||
if (val&0x10) LOG_DEBUG("CMOS:Updated ended interrupt not supported yet");
|
||||
if (val&0x10) LOG(LOG_ERROR|LOG_BIOS,"CMOS:Updated ended interrupt not supported yet");
|
||||
cmos_checktimer();
|
||||
break;
|
||||
default:
|
||||
cmos.regs[cmos.reg]=val & 0x7f;
|
||||
LOG_DEBUG("CMOS:Unhandled register %x",cmos.reg);
|
||||
LOG(LOG_ERROR|LOG_BIOS,"CMOS:Unhandled register %x",cmos.reg);
|
||||
}
|
||||
}
|
||||
|
||||
static Bit8u cmos_readreg(Bit32u port) {
|
||||
if (cmos.reg>0x3f) {
|
||||
LOG_DEBUG("CMOS:Read from illegal register %x",cmos.reg);
|
||||
LOG(LOG_ERROR|LOG_BIOS,"CMOS:Read from illegal register %x",cmos.reg);
|
||||
return 0xff;
|
||||
}
|
||||
switch (cmos.reg) {
|
||||
@ -115,4 +115,5 @@ void CMOS_Init(Section* sec) {
|
||||
IO_RegisterWriteHandler(0x71,cmos_writereg,"CMOS");
|
||||
IO_RegisterReadHandler(0x71,cmos_readreg,"CMOS");
|
||||
cmos.timer.enabled=false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,21 @@
|
||||
/*
|
||||
* Copyright (C) 2002-2003 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "dosbox.h"
|
||||
#include "inout.h"
|
||||
@ -20,8 +38,6 @@ static struct {
|
||||
Bit8u control;
|
||||
Bit8u buffer[DISNEY_SIZE];
|
||||
Bitu used;
|
||||
bool enabled;
|
||||
Bit8u delay;
|
||||
MIXER_Channel * chan;
|
||||
} disney;
|
||||
|
||||
@ -31,7 +47,7 @@ static void disney_write(Bit32u port,Bit8u val) {
|
||||
disney.data=val;
|
||||
break;
|
||||
case 1: /* Status Port */
|
||||
LOG_WARN("DISNEY:Status write %x",val);
|
||||
LOG(LOG_MISC,"DISNEY:Status write %x",val);
|
||||
break;
|
||||
case 2: /* Control Port */
|
||||
// LOG_WARN("DISNEY:Control write %x",val);
|
||||
@ -40,7 +56,7 @@ static void disney_write(Bit32u port,Bit8u val) {
|
||||
disney.buffer[disney.used++]=disney.data;
|
||||
}
|
||||
}
|
||||
if (val&0x10) LOG_DEBUG("IRQ Enabled");
|
||||
if (val&0x10) LOG(LOG_ERROR,"DISNEY:Parallel IRQ Enabled");
|
||||
disney.control=val;
|
||||
break;
|
||||
}
|
||||
@ -50,16 +66,16 @@ static Bit8u disney_read(Bit32u port) {
|
||||
|
||||
switch (port-DISNEY_BASE) {
|
||||
case 0: /* Data Port */
|
||||
LOG_WARN("DISNEY:Read from data port");
|
||||
// LOG(LOG_MISC,"DISNEY:Read from data port");
|
||||
return disney.data;
|
||||
break;
|
||||
case 1: /* Status Port */
|
||||
// LOG_WARN("DISNEY:Read from status port %X",disney.status);
|
||||
// LOG(LOG_MISC,"DISNEY:Read from status port %X",disney.status);
|
||||
if (disney.used>=16) return 0x40;
|
||||
else return 0x0;
|
||||
break;
|
||||
case 2: /* Control Port */
|
||||
LOG_WARN("DISNEY:Read from control port");
|
||||
LOG(LOG_MISC,"DISNEY:Read from control port");
|
||||
return disney.control;
|
||||
break;
|
||||
}
|
||||
@ -83,6 +99,10 @@ static void DISNEY_CallBack(Bit8u * stream,Bit32u len) {
|
||||
|
||||
|
||||
void DISNEY_Init(Section* sec) {
|
||||
MSG_Add("DISNEY_CONFIGFILE_HELP","Nothing to setup yet!\n");
|
||||
Section_prop * section=static_cast<Section_prop *>(sec);
|
||||
if(!section->Get_bool("enabled")) return;
|
||||
|
||||
IO_RegisterWriteHandler(DISNEY_BASE,disney_write,"DISNEY");
|
||||
IO_RegisterWriteHandler(DISNEY_BASE+1,disney_write,"DISNEY");
|
||||
IO_RegisterWriteHandler(DISNEY_BASE+2,disney_write,"DISNEY");
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2002 The DOSBox Team
|
||||
* Copyright (C) 2002-2003 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -21,10 +21,8 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
Still need to implement reads from dma ports :)
|
||||
Perhaps sometime also implement dma writes.
|
||||
DMA transfer that get setup with a size 0 are also done wrong should be 0x10000 probably.
|
||||
|
||||
TODO
|
||||
Implement 16-bit dma
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
@ -32,6 +30,7 @@
|
||||
#include "mem.h"
|
||||
#include "inout.h"
|
||||
#include "dma.h"
|
||||
#include "pic.h"
|
||||
|
||||
#if DEBUG_DMA
|
||||
#define DMA_DEBUG LOG_DEBUG
|
||||
@ -47,8 +46,8 @@
|
||||
struct DMA_CHANNEL {
|
||||
struct {
|
||||
Bit8u mode_type;
|
||||
Bit8u address_decrement;
|
||||
Bit8u autoinit_enable;
|
||||
bool address_decrement;
|
||||
bool autoinit_enable;
|
||||
Bit8u transfer_type;
|
||||
} mode;
|
||||
Bit16u base_address;
|
||||
@ -59,6 +58,7 @@ struct DMA_CHANNEL {
|
||||
bool masked;
|
||||
PhysPt address;
|
||||
bool addr_changed;
|
||||
DMA_EnableCallBack enable_callback;
|
||||
};
|
||||
|
||||
|
||||
@ -96,9 +96,13 @@ static Bit8u read_dma(Bit32u port) {
|
||||
ret=cont->status_reg;
|
||||
cont->status_reg&=0xf; /* Clear lower 4 bits on read */
|
||||
break;
|
||||
|
||||
case 0x0a:
|
||||
case 0x0e:
|
||||
/* Seem to return 0 on a real controller */
|
||||
ret=0x0;
|
||||
break;
|
||||
default:
|
||||
LOG_WARN("DMA:Unhandled read from %d",port);
|
||||
LOG(LOG_ERROR,"DMA:Unhandled read from %X",port);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -107,9 +111,10 @@ static Bit8u read_dma(Bit32u port) {
|
||||
static void write_dma(Bit32u port,Bit8u val) {
|
||||
/* only use first dma for now */
|
||||
DMA_CONTROLLER * cont=&dma[0];
|
||||
DMA_CHANNEL * chan=&cont->chan[port>>1];
|
||||
DMA_CHANNEL * chan;
|
||||
switch (port) {
|
||||
case 0x00:case 0x02:case 0x04:case 0x06:
|
||||
chan=&cont->chan[port>>1];
|
||||
if (cont->flipflop) {
|
||||
chan->base_address=(chan->base_address & 0xff00) | val;
|
||||
} else {
|
||||
@ -119,6 +124,7 @@ static void write_dma(Bit32u port,Bit8u val) {
|
||||
chan->addr_changed=true;
|
||||
break;
|
||||
case 0x01:case 0x03:case 0x05:case 0x07:
|
||||
chan=&cont->chan[port>>1];
|
||||
if (cont->flipflop) {
|
||||
chan->base_count=(chan->base_count & 0xff00) | val;
|
||||
} else {
|
||||
@ -128,7 +134,7 @@ static void write_dma(Bit32u port,Bit8u val) {
|
||||
chan->addr_changed=true;
|
||||
break;
|
||||
case 0x08: /* Command Register */
|
||||
if (val != 4) LOG_WARN("DMA1:Illegal command %2X",val);
|
||||
if (val != 4) LOG(LOG_ERROR,"DMA1:Illegal command %2X",val);
|
||||
cont->command_reg=val;
|
||||
break;
|
||||
case 0x09: /* Request Register */
|
||||
@ -142,22 +148,27 @@ static void write_dma(Bit32u port,Bit8u val) {
|
||||
}
|
||||
break;
|
||||
case 0x0a: /* single mask bit register */
|
||||
chan=&cont->chan[val & 0x3];
|
||||
chan->masked=(val & 4)>0;
|
||||
if (chan->enable_callback) chan->enable_callback(!chan->masked);
|
||||
break;
|
||||
case 0x0b: /* mode register */
|
||||
chan=&cont->chan[val & 0x3];
|
||||
chan->mode.mode_type = (val >> 6) & 0x03;
|
||||
chan->mode.address_decrement = (val >> 5) & 0x01;
|
||||
chan->mode.autoinit_enable = (val >> 4) & 0x01;
|
||||
chan->mode.address_decrement = (val & 0x20) > 0;
|
||||
chan->mode.autoinit_enable = (val & 0x10) > 0;
|
||||
chan->mode.transfer_type = (val >> 2) & 0x03;
|
||||
if (chan->mode.address_decrement) {
|
||||
LOG_WARN("DMA:Address Decrease not supported yet");
|
||||
LOG(LOG_ERROR,"DMA:Address Decrease not supported yet");
|
||||
}
|
||||
|
||||
break;
|
||||
case 0x0c: /* Clear Flip/Flip */
|
||||
cont->flipflop=true;
|
||||
break;
|
||||
};
|
||||
default:
|
||||
LOG(LOG_ERROR,"DMA:Unhandled write %X to %X",val,port);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@ -177,21 +188,20 @@ void write_dma_page(Bit32u port,Bit8u val) {
|
||||
dma[0].chan[channel].addr_changed=true;
|
||||
}
|
||||
|
||||
Bit16u DMA_8_Read(Bit32u dmachan,Bit8u * buffer,Bit16u count) {
|
||||
|
||||
INLINE void ResetDMA8(DMA_CHANNEL * chan) {
|
||||
chan->addr_changed=false;
|
||||
chan->address=(chan->page << 16)+chan->base_address;
|
||||
chan->current_count=chan->base_count+1;
|
||||
chan->current_address=chan->base_address;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Bitu DMA_8_Read(Bitu dmachan,Bit8u * buffer,Bitu count) {
|
||||
DMA_CHANNEL * chan=&dma[0].chan[dmachan];
|
||||
|
||||
if (chan->masked) return 0;
|
||||
if (!count) return 0;
|
||||
/* DMA always does autoinit should work under normal situations */
|
||||
if (chan->addr_changed) {
|
||||
/* Calculate the new starting position for dma read*/
|
||||
chan->addr_changed=false;
|
||||
chan->address=(chan->page << 16)+chan->base_address;
|
||||
|
||||
chan->current_count=chan->base_count+1;
|
||||
chan->current_address=chan->base_address;
|
||||
DMA_DEBUG("DMA:Transfer from %d size %d",(chan->page << 16)+chan->base_address,chan->current_count);
|
||||
}
|
||||
if (chan->masked || !count) return 0;
|
||||
if (chan->addr_changed) ResetDMA8(chan);
|
||||
if (chan->current_count>count) {
|
||||
MEM_BlockRead(chan->address,buffer,count);
|
||||
chan->address+=count;
|
||||
@ -204,17 +214,15 @@ Bit16u DMA_8_Read(Bit32u dmachan,Bit8u * buffer,Bit16u count) {
|
||||
if (!chan->mode.autoinit_enable) {
|
||||
/* Set the end of counter bit */
|
||||
dma[0].status_reg|=(1 << dmachan);
|
||||
count=(Bit16u)chan->current_count;
|
||||
count=chan->current_count;
|
||||
chan->current_address+=count;;
|
||||
chan->current_count=0;
|
||||
return count;
|
||||
} else {
|
||||
buffer+=chan->current_count;
|
||||
Bit16u left=count-(Bit16u)chan->current_count;
|
||||
Bitu left=count-(Bit16u)chan->current_count;
|
||||
/* Autoinit reset the dma channel */
|
||||
chan->address=(chan->page << 16)+chan->base_address;
|
||||
chan->current_count=chan->base_count+1;
|
||||
chan->current_address=chan->base_address;
|
||||
ResetDMA8(chan);
|
||||
/* Copy the rest of the buffer */
|
||||
MEM_BlockRead(chan->address,buffer,left);
|
||||
chan->address+=left;
|
||||
@ -223,22 +231,52 @@ Bit16u DMA_8_Read(Bit32u dmachan,Bit8u * buffer,Bit16u count) {
|
||||
return count;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Bit16u DMA_8_Write(Bit32u dmachan,Bit8u * buffer,Bit16u count) {
|
||||
|
||||
return 0;
|
||||
};
|
||||
Bitu DMA_8_Write(Bitu dmachan,Bit8u * buffer,Bitu count) {
|
||||
DMA_CHANNEL * chan=&dma[0].chan[dmachan];
|
||||
if (chan->masked || !count) return 0;
|
||||
if (chan->addr_changed) ResetDMA8(chan);
|
||||
if (chan->current_count>count) {
|
||||
MEM_BlockWrite(chan->address,buffer,count);
|
||||
chan->address+=count;
|
||||
chan->current_address+=count;
|
||||
chan->current_count-=count;
|
||||
return count;
|
||||
} else {
|
||||
/* Copy remaining piece of first buffer */
|
||||
MEM_BlockWrite(chan->address,buffer,chan->current_count);
|
||||
if (!chan->mode.autoinit_enable) {
|
||||
/* Set the end of counter bit */
|
||||
dma[0].status_reg|=(1 << dmachan);
|
||||
count=chan->current_count;
|
||||
chan->current_address+=count;;
|
||||
chan->current_count=0;
|
||||
return count;
|
||||
} else {
|
||||
buffer+=chan->current_count;
|
||||
Bitu left=count-(Bit16u)chan->current_count;
|
||||
/* Autoinit reset the dma channel */
|
||||
ResetDMA8(chan);
|
||||
/* Copy the rest of the buffer */
|
||||
MEM_BlockWrite(chan->address,buffer,left);
|
||||
chan->address+=left;
|
||||
chan->current_address+=left;
|
||||
chan->current_count-=left;
|
||||
return count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Bit16u DMA_16_Read(Bit32u dmachan,Bit8u * buffer,Bit16u count) {
|
||||
Bitu DMA_16_Read(Bitu dmachan,Bit8u * buffer,Bitu count) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Bit16u DMA_16_Write(Bit32u dmachan,Bit8u * buffer,Bit16u count) {
|
||||
Bitu DMA_16_Write(Bitu dmachan,Bit8u * buffer,Bitu count) {
|
||||
|
||||
|
||||
return 0;
|
||||
@ -247,6 +285,18 @@ Bit16u DMA_16_Write(Bit32u dmachan,Bit8u * buffer,Bit16u count) {
|
||||
|
||||
|
||||
|
||||
void DMA_SetEnableCallBack(Bitu channel,DMA_EnableCallBack callback) {
|
||||
if (channel<4) {
|
||||
dma[0].chan[channel].enable_callback=callback;
|
||||
if (callback) callback(!dma[0].chan[channel].masked);
|
||||
return;
|
||||
}
|
||||
if (channel<8) {
|
||||
dma[1].chan[channel-4].enable_callback=callback;
|
||||
if (callback) callback(!dma[1].chan[channel-4].masked);
|
||||
}
|
||||
}
|
||||
|
||||
void DMA_Init(Section* sec) {
|
||||
for (Bit32u i=0;i<0x10;i++) {
|
||||
IO_RegisterWriteHandler(i,write_dma,"DMA1");
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user