mirror of
https://github.com/retro100/dosbox-wii.git
synced 2024-09-28 17:58:36 +02:00
DOSBox 0.50
This commit is contained in:
parent
54be7b3aac
commit
acd61d619e
11
AUTHORS
11
AUTHORS
@ -1,11 +1,8 @@
|
|||||||
The DOSBox Team
|
The DOSBox Team
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
Sjoerd v.d. Berg <harekiet>
|
Sjoerd v.d. Berg <harekiet@zophar.net>
|
||||||
Peter Veenstra <qbix79>
|
Peter Veenstra <qbix79@users.sourceforge.net>
|
||||||
Ulf Wohlers <finsterr>
|
|
||||||
Tommy Frössman <fanskapet>
|
|
||||||
Dean Beeler <canadacow>
|
|
||||||
Sebastian Strohhäcker <c2woody>
|
|
||||||
|
|
||||||
nick_without_<> @ users.sourceforge.net
|
|
||||||
|
510
ChangeLog
510
ChangeLog
@ -1,509 +1,3 @@
|
|||||||
0.72
|
|
||||||
- Fixed unitialized variable in joystick. (Fixes crashes on Vista and
|
|
||||||
Mac OS X)
|
|
||||||
- Some bugfixes and speedups to the 64 bit recompiling core.
|
|
||||||
- Fixed sign flag on soundblaster dma transfers (Space Quest 6 intro)
|
|
||||||
- Fixed a bug in keyboard layout processing code and fixed certain
|
|
||||||
layouts.
|
|
||||||
- Fixed Dreamweb.
|
|
||||||
- Improved speed unlocking when running cycles=max.
|
|
||||||
- Fixed a crash related to the tab completion in the shell.
|
|
||||||
- Improved aspect correction code. Should now be like how a real monitor
|
|
||||||
handles it.
|
|
||||||
- Fixed a bug in the xms status report code. (Blake Stone 1.0 shareware)
|
|
||||||
- Added a lot more keyboard layouts.
|
|
||||||
- Fix crash related to changing the scaler before a screen was created.
|
|
||||||
- Hopefully fixed compilation on *bsd.
|
|
||||||
- Enabled auto cpu core selection for recompiling core as well.
|
|
||||||
- Made the used joystick selectable when 4axis is specified.
|
|
||||||
- Added some hints for inexperienced DOS users to the shell.
|
|
||||||
|
|
||||||
0.71
|
|
||||||
- Add a new recompiling cpu core, which should be easier to port.
|
|
||||||
- Add 64 bit version of the recompiling core.
|
|
||||||
- Add mipsel 32 bit version of the recompiling core.
|
|
||||||
- Fix a few small problems with FCBs. (fixes Jewels of darkness and
|
|
||||||
cyrus chess)
|
|
||||||
- Raise some more exceptions. (fixes vbdos)
|
|
||||||
- Fix a few problems with the dynamic core. (fixes Inner Words,
|
|
||||||
Archmimedean Dynasty and others)
|
|
||||||
- Improve/Fix fallback code for certain graphics cards.
|
|
||||||
- Fix a few cd audio related bugs.
|
|
||||||
- Add an undocumented MSCDEX feature. (Fixes Ultimate Domain)
|
|
||||||
- Fix some pcspeaker mode. (fixes Test Drive and similar games)
|
|
||||||
- Improve dos keyinput handling. (fixes Wing Commander 3 exit dialog)
|
|
||||||
- Remove Exit condition on fully nested mode. (fixes some demo)
|
|
||||||
- Add image file size detection.
|
|
||||||
- Add/Fix some ansi codes. (fixes PC Larn and certain versions of
|
|
||||||
infocom games)
|
|
||||||
- Several general DOS fixes. (fixes nba95, hexit and various other games)
|
|
||||||
- Add some valid input checks. (fixes 3d body adventure and similar
|
|
||||||
games)
|
|
||||||
- Fix digital joystick centering problem.
|
|
||||||
- Reenable textmode 54 and 55.
|
|
||||||
- Fix a pelmask problem with univbe 5.0 lite. (fixes Panzer General)
|
|
||||||
- Fix minor mixer underflow.
|
|
||||||
- Some general image and bios disk emulation fixes.
|
|
||||||
- Hopefully fix compilation on BSD and darwin.
|
|
||||||
- Try using ioctl cdrom access by default if possible.
|
|
||||||
- Fix some svga detection routine. (fixes Grandest Fleet 2 and Bobby Fischer
|
|
||||||
Teaches Chess)
|
|
||||||
- You can now close DOSBox using the status window in win32.
|
|
||||||
- Add support for NX enabled systems.
|
|
||||||
- Fix a casting error which only showed with certain compilers. (fixes
|
|
||||||
various games under mac os x and 64 bit linux)
|
|
||||||
- Improve timer and add gate 2 support. (fixes various games and
|
|
||||||
joystick problems)
|
|
||||||
- Improve mouse. Add undocumented backdoor. (fixes Last half of Darkness,
|
|
||||||
PC-BLOX and others)
|
|
||||||
- Add/improve support for ~ and ~username in all commands.
|
|
||||||
- Fix a font problem with the pcjr/tandy. (fixes personal deskmate 2)
|
|
||||||
- Change dma routine a bit. (fixes ticks in sound in various games)
|
|
||||||
- Allow read-only diskimages to be booted. (fixes various booter
|
|
||||||
games)
|
|
||||||
- Add basic hidden file support on cdrom images. (fixes Player
|
|
||||||
Manager 2)
|
|
||||||
- Add some rarely used functionality to the int10 mode setup. (fixes
|
|
||||||
WW2 Battles of the South pacific)
|
|
||||||
- Add ability to force scaler usage.
|
|
||||||
- Speed up flag generation and make it more 386-like.
|
|
||||||
- Some colourful feedback in the mapper.
|
|
||||||
- General code cleanup.
|
|
||||||
|
|
||||||
0.70
|
|
||||||
- Improve register handling and support with XMS.
|
|
||||||
- Fix some issues with deleting open files.(windows only issue)
|
|
||||||
- Add dummy LPT1 class. (windows only issue)
|
|
||||||
- Improve some of the internal dos commands. (choice, copy and shift)
|
|
||||||
- Improve ROM area. (for games that use it for random numbers or
|
|
||||||
overwrite it as some sort of detection thing)
|
|
||||||
- Improve compatibility of dynamic core by making it handle certain
|
|
||||||
pagefaults earlier.
|
|
||||||
- Move internal dos tables around so we have more umb memory.
|
|
||||||
- Add some dos tables.
|
|
||||||
- Dynamic core supports io exceptions.
|
|
||||||
- Move some interrupt handlers to XT Bios locations.
|
|
||||||
- Add a dynamic fpu on x86.
|
|
||||||
- Improve fpu on non-x86.
|
|
||||||
- Trapflag gets strict priority over hardware IRQs.
|
|
||||||
- Trapflag support for the dynamic core.
|
|
||||||
- Add dummy TRx handling.
|
|
||||||
- Fix a few rarely used character functions.
|
|
||||||
- Improve auto cycle guessing code.
|
|
||||||
- Improve and extend the joystick support.
|
|
||||||
- Add autofire support.
|
|
||||||
- Improve the mapper so you can map keys to the joystick and vice versa.
|
|
||||||
- A few game specific video card fixes.
|
|
||||||
- Fix some 64 bit cpu bugs.
|
|
||||||
- Add support for certain cdrom detection schemes.
|
|
||||||
- Improve HSG/Red Book support.
|
|
||||||
- Improve MSCDEX.
|
|
||||||
- Improve dynamic core support under intel macs.
|
|
||||||
- Add basic support for clipper programs.
|
|
||||||
- Add support for different keyboard layouts.
|
|
||||||
- Add auto core guessing.
|
|
||||||
- Fix a few flags bugs.
|
|
||||||
- Fix a few small cpu bugs.
|
|
||||||
- Improve soundblaster detection rate by various programs.
|
|
||||||
- Improve EMS emulation. (allow mapping of non standard regions)
|
|
||||||
- Improve keyboard input codes on various OS-es.
|
|
||||||
- Fix problems with filenames having stackdata in them.
|
|
||||||
- Changed a few basic operations in DOSBox so they take emulated time.
|
|
||||||
- Improve dos ioctl functions.
|
|
||||||
- Extend cpu core so they are capable of detecting and raising a few
|
|
||||||
more exception types.
|
|
||||||
- Improve DOS functions when dealing with virtual drive.
|
|
||||||
- Improve FAT drives.
|
|
||||||
- Better handling of volume-labels in file functions.
|
|
||||||
- Image disk cycling capability. (prompt)
|
|
||||||
- Try to reduce the impact of using an analog joystick.
|
|
||||||
- Several measures to avoid code invalidation on certain types
|
|
||||||
of self modification in the dynamic core.
|
|
||||||
- Add dynamic core memory function inlining.
|
|
||||||
- A few small mouse improvements. (some games are using things they
|
|
||||||
shouldn't)
|
|
||||||
- Add nullmodem emulation.(h-a-l-9000)
|
|
||||||
- Some small cga and hercules fixes.
|
|
||||||
- Add more scalers (hq2x/hq3x/sai). (Kronuz)
|
|
||||||
- Change configuration file loading support. It now supports
|
|
||||||
multiple configuration files.
|
|
||||||
- Make dynamic core capable of running some win32s programs.
|
|
||||||
- Fix and add some rare soundblaster modes. (Srecko)
|
|
||||||
- Better soundblaster mixer controls. (Srecko)
|
|
||||||
- Make soundblaster installation under windows much easier.
|
|
||||||
- Add device control channel handling.
|
|
||||||
- GEMMIS support (ems under windows).
|
|
||||||
- Support more colours in win 3. (vasyl)
|
|
||||||
- Don't show unmounted drives in windows filemanager.
|
|
||||||
- Fix some bugs in the int13 handler.
|
|
||||||
- Simulate some side-effects of bios interrupt handlers on flags.
|
|
||||||
- Add IPX functions needed by netbios.
|
|
||||||
- Make ports take emulated time.
|
|
||||||
- Tabcompletion is now aware of the CD command.
|
|
||||||
- Add suppport for the dac pel mask.
|
|
||||||
- Fixes to hercules emulation, better detection and bank switching.
|
|
||||||
- Fixes to tandy emulation, 640x200x16 mode and different sizes bank.
|
|
||||||
- EGA/VGA memory changes detection for faster rendering.
|
|
||||||
- Gus 16 bit fixes.
|
|
||||||
- Many timer improvements.
|
|
||||||
- Some pcjr fixes.
|
|
||||||
- Some booter fixes.
|
|
||||||
- Many small fixes.
|
|
||||||
|
|
||||||
0.65
|
|
||||||
- Fixed FAT writing.
|
|
||||||
- Added some more missing DOS functions.
|
|
||||||
- Improved PIC so that it actually honours irq 2/9.
|
|
||||||
- Improved intelligent MPU-401 mode so that more games work with it.
|
|
||||||
- Some mouse fixes.
|
|
||||||
- Changed DMA transfers a bit so they bypass the paging tables.
|
|
||||||
- Added S3 XGA functionality.
|
|
||||||
- Improved paging so that read and write faults are handled differently.
|
|
||||||
- Rewrote exception handling a bit (no exception 0x0B with dos4gw anymore).
|
|
||||||
- Added IO exceptions in all but the dynamic core.
|
|
||||||
- Some ems improvements.
|
|
||||||
- Added midi-device selection code for the windows hosts.
|
|
||||||
- Fix crashes/segfaults related to the disabling of the pcspeaker.
|
|
||||||
- Added some more FILES=XX detection tricks.
|
|
||||||
- Fixed some vga detection schemes.
|
|
||||||
- Fixed screenshot corruption when using -noconsole in a read-only directory.
|
|
||||||
- Fix wrong scaled screenshots.
|
|
||||||
- Added some hidden file functions when using diskimages. (helps with cdrom
|
|
||||||
detection schemes)
|
|
||||||
- Fixed a bug in the mixer code, that muted the music in certain games.
|
|
||||||
- Added an assembly fpu core.
|
|
||||||
- Made the shell more flexible for batch files.
|
|
||||||
- Check for unaligned memory acces fixes hangups on ARM processors.
|
|
||||||
- Some 64 bit fixes.
|
|
||||||
- Added code to change configuration at runtime.
|
|
||||||
- Improved ADPCM emulation.
|
|
||||||
- Fixed a few cpu instructions.
|
|
||||||
- Always report vesa 2.0 and fix some colour issues with vesa games.
|
|
||||||
- Fix video mode 0x06 and 0x0a.
|
|
||||||
- Improvements to the joystick emulation. 4 buttons are supported as well.
|
|
||||||
- Add VCPI emulation for Origin games.
|
|
||||||
- Fixed a lot of things in the boot code. Most booters work now.
|
|
||||||
- Lots of improvements to the IPX emulation.
|
|
||||||
- Rewritten modem emulation. Should work with more games.
|
|
||||||
- Improvements to the dos memory managment routines.
|
|
||||||
- Add UMB (upper memory blocks) support.
|
|
||||||
- Emulate the pause key.
|
|
||||||
- Improve Composite CGA mode emulation.
|
|
||||||
- Lots of vga compatibility changes.
|
|
||||||
- Improved support for chained video modes.
|
|
||||||
- Improved mode and palette handling in cga modes.
|
|
||||||
- Mount accepts ~ now.
|
|
||||||
- Added a few of the EGA RIL functions.
|
|
||||||
- Added TandyDAC emulation.
|
|
||||||
- OS/2 support.
|
|
||||||
- Improved and speed up the dynamic cpu core.
|
|
||||||
- Fix some errors in the CD-ROM emulation layer.
|
|
||||||
- Added an automatic work-around for some graphics chipsets.
|
|
||||||
- Add PCjr support.
|
|
||||||
- Allow mousedriver to be replaced. Fixes a few games that come with their
|
|
||||||
own (internal) driver.
|
|
||||||
- Improved dynamic cpu core so it can handle pagefaults and some obscure
|
|
||||||
types of self-modifying code.
|
|
||||||
- Added -noautoexec switch to skip the contents of [autoexec] in the
|
|
||||||
configuration file.
|
|
||||||
- Improved v86 mode emulation (mainly for Strike Commander).
|
|
||||||
- Improved timer behavior.
|
|
||||||
- Improved extended keyboard support.
|
|
||||||
- Enhanced and added several DOS tables.
|
|
||||||
- Made core_full endian safe.
|
|
||||||
- Made pagefaults endian safe.
|
|
||||||
- Add support for moviecapturing
|
|
||||||
- Add support for 15/16/32 bit videomodes.
|
|
||||||
- Add some more VESA modi (4 bit).
|
|
||||||
- Add 1024x768 output.
|
|
||||||
- Changed screenrendering so it only draws changes to the screen.
|
|
||||||
- Allow remapping of the EMS page when the dma transfer was started from
|
|
||||||
the page frame
|
|
||||||
- Made EMS and DMA work together when playing from a mapped memory page.
|
|
||||||
- Renamed several configuration options, so that they are unique.
|
|
||||||
- Merged mpu and intelligent into one option.
|
|
||||||
- Merged fullfixed and fullresolution.
|
|
||||||
- Extended keys should be handled better.
|
|
||||||
- F11 and F12 work.
|
|
||||||
- Compilation fixes for various platforms.
|
|
||||||
- Fix a few crashes when giving bad input.
|
|
||||||
- Removed interp2x and added few new scalers.
|
|
||||||
- Reintroduce the lockfree mouse. (autolock=false)
|
|
||||||
- Add a larger cache for the dynamic cpu core.
|
|
||||||
- Improved soundblaster DSP, so it gets detected by creative tools.
|
|
||||||
- Lots of bugfixes.
|
|
||||||
- Even more bugfixes.
|
|
||||||
|
|
||||||
0.63
|
|
||||||
- Fixed crash with keymapper (ctrl-f1) and output=surface.
|
|
||||||
- Added unmounting.
|
|
||||||
- Fixed multiple issues with drive labels.
|
|
||||||
- Fixed most if not all FILES=XX problems.
|
|
||||||
- Added redirection in the shell.
|
|
||||||
- Fixed crashes with subst.
|
|
||||||
- Fixed multiple crashes with the drive images support.
|
|
||||||
- Added a missing fpu instruction.
|
|
||||||
- Fixed some cpu and fpu instructions.
|
|
||||||
- Fixed a small bug related to font loading.
|
|
||||||
- Rewrote the devices support.
|
|
||||||
- Added capslock/numlock checks on startup.
|
|
||||||
- Fixed wave writing.
|
|
||||||
- A few internal DOS fixes.
|
|
||||||
- Timer fixes for the hybrid loader.
|
|
||||||
- Some small soundblaster fixes.
|
|
||||||
- The drive cache can now be cleared by a keycombo. (CTRL-F4)
|
|
||||||
- A few keyboard fixes.
|
|
||||||
- Compilation fixes on various platforms.
|
|
||||||
- Quite some debugger improvements.
|
|
||||||
- Fixed dir only showing files after the first run on cdrom drives.
|
|
||||||
- Added some cdrom detection checks.
|
|
||||||
- Enabled insert in the shell. (Easier editing of commands)
|
|
||||||
- Changed order in which executables appear with tab-completion.
|
|
||||||
- Fixed some issues with raw opl recording and using a slightly different
|
|
||||||
format
|
|
||||||
|
|
||||||
0.62
|
|
||||||
- Added blinking support in the shell and some color fixes.
|
|
||||||
- Fixed commandline parsing when .bat files involved (fixes -exit)
|
|
||||||
- Fixed issues with tabs in commandline not being processed correctly.
|
|
||||||
- Cleaned/improved shutdown sequence.
|
|
||||||
- Added some more bios functions (wait and delay functions).
|
|
||||||
- Made our XMS driver conform the specs better. (c2woody)
|
|
||||||
- Added support for some more ems functions.
|
|
||||||
- Added intelligent mpu401 emulation. (Srecko)
|
|
||||||
- Added soundblaster 16 emulation.
|
|
||||||
- Rewrote GUS emulation to sound more authentic.
|
|
||||||
- Improved pc speaker emulation.
|
|
||||||
- Added an internal (programmable) mixer.
|
|
||||||
- Added support a few soundblaster/adlib detection routines.
|
|
||||||
- Fixed lot's of bugs related to DMA transfers.
|
|
||||||
- Added interpolating prebuffering mixer routines.
|
|
||||||
- Added recording of OPL commands and raw midi.
|
|
||||||
- Fixed some bugs with the wave recording.
|
|
||||||
- Changed sensitivity settings of the mouse.
|
|
||||||
- Added ps2 mouse-emulation in bios interrupts (c2woody).
|
|
||||||
- Fixed some bugs with mouse emulation limits.
|
|
||||||
- Fixed a bug with an unterminated string in the drivelabel.
|
|
||||||
- Changed file search routines a bit to be more compatible.
|
|
||||||
- Added support for attribute-searching with fcb's.
|
|
||||||
- Added basic SDA.
|
|
||||||
- Added TPA and DIB.
|
|
||||||
- Added Lot's of missing dos tables (c2woody).
|
|
||||||
- Changed psp and dta functions to use dta.
|
|
||||||
- Returned filename in ds:dx in create-random-file (c2woody).
|
|
||||||
- Fixed a bug with date and time used on open files.
|
|
||||||
- Some mscdex fixes.
|
|
||||||
- Added the -version switch, which makes dosbox report its version.
|
|
||||||
- Added a keymapper.
|
|
||||||
- Added basic IPX emulation.
|
|
||||||
- Added cdrom iso support and floppy images support.
|
|
||||||
- Added the possibity to boot another dos version.
|
|
||||||
- Added Serial passthrough support (win32 only).
|
|
||||||
- Added the possibility to pause dosbox.
|
|
||||||
- Changed OpenGL so that it is initialized only when used.
|
|
||||||
- Make dosbox run at higher priority when active and lower when inactive.
|
|
||||||
- Added direct draw output support (win32 only).
|
|
||||||
- Added current running program to title bar.
|
|
||||||
- Rewrote video emulation to support new scalers.
|
|
||||||
- Added new graphics scalers like advmame3x,tv2x.
|
|
||||||
- Added a support for a few anti-debugger tricks.
|
|
||||||
- Improved the handling of the tab-key.
|
|
||||||
- Improved support for the numeric keyboard.
|
|
||||||
- Fixed a few cpu opcodes.
|
|
||||||
- Added cpu core simple (for lowerend machines)
|
|
||||||
- Fixed some nasty bugs in the dynamic cpu core.
|
|
||||||
- Added a few (rarely used) fpu opcodes.
|
|
||||||
- Fixed various issues with GCC 3.4.
|
|
||||||
- Many internal timer improvements (PIT and PIC).
|
|
||||||
- Added some more PIC commands (c2woody).
|
|
||||||
- Added BCD counting to the timers.
|
|
||||||
- Fix some vesa functions.
|
|
||||||
- Add some basic support for 132x25 and 132x45 textmodes.
|
|
||||||
- Improved Tandy emulation a lot.
|
|
||||||
- Lowered cpu usage when dosbox is idle.
|
|
||||||
- Allow virtualisation of some basic IO-ports (c2woody).
|
|
||||||
|
|
||||||
|
|
||||||
0.61
|
|
||||||
- Added a beta dynamic cpu for x86 hosts (very unstable)
|
|
||||||
- Added opengl and hardware overlay display output
|
|
||||||
- Rewrote the vga screen updates to go in lines
|
|
||||||
- Added paging and v86 support to cpu emulation
|
|
||||||
- Added a config option to simulate a certain type of machine
|
|
||||||
- Added hercules graphics emulation
|
|
||||||
- Made CGA/TANDY modes more compatible
|
|
||||||
- Updated textmode drawing routines to support blinking colors
|
|
||||||
- Fixed VESA set page function that was documented wrong
|
|
||||||
- Fixed some wrongly emulated cpu opcodes.
|
|
||||||
- improved exception handling
|
|
||||||
- debugger: fixes; logging of gdt,lgt,idt, new commands(Fizzban)
|
|
||||||
- fixed some mscdex issues (drive letter header error, added get directory entry)
|
|
||||||
- added/fixed some bios funcs
|
|
||||||
- added some rarely used xms functions (thanks c2woody!)
|
|
||||||
- implemented GUS emulation
|
|
||||||
- Added 16-bit DMA support (for GUS and eventually SB16)
|
|
||||||
- Fixed many small bugs in filehandling routines
|
|
||||||
- Many small FPU fixes (c2woody/Fizzban)
|
|
||||||
- Some keyboard improvements (pharlab games)
|
|
||||||
- Some Timer and cmos/rtc fixes (Mirek/Srecko/Others)
|
|
||||||
- Lot's of mouse fixes (Help from various people)
|
|
||||||
- Enabled internal modem
|
|
||||||
- Made the DOS parsing routines a bit more flexible
|
|
||||||
- Added Subst (Srecko)
|
|
||||||
- Added cdrom ioctl support for linux (prompt)
|
|
||||||
- Many internal DOS fixes: memory/files/datastructures.
|
|
||||||
- Got some help from c2woody in allowing more than 1 irq being served
|
|
||||||
- Disabled DPMI (not needed anymore. DOSBox handles almost every extender)
|
|
||||||
- Search configfile in $HOME directory if none present in current directory
|
|
||||||
- Added another way to switch to protected mode. (Thanks Morten Eriksen!)
|
|
||||||
- Fixed some odd badly documented behaviour with PSP/DTA
|
|
||||||
- Added some warnings on opening of readonly files in writemode(DOS default).
|
|
||||||
- Many shell enhanchements
|
|
||||||
- Fixed a win32 specific bug dealing with filenames starting with a "."
|
|
||||||
- Fixed some bugs with the directory structure: not found/can't save errors
|
|
||||||
|
|
||||||
0.60
|
|
||||||
- rewrote memory system for future paging support
|
|
||||||
- fixed several EMS and XMS bugs and rewrite for new memory system
|
|
||||||
- added some support for tandy video modes
|
|
||||||
- added MAME Tandy 3 voice emulation
|
|
||||||
- added MAME CMS/GameBlaster emulation
|
|
||||||
- added serial port emulation with virtual tcp/ip modem (somewhat buggy)
|
|
||||||
- sound blaster emulation is now sb pro 2.0 compatible
|
|
||||||
- added basic support for 32-bit protected mode
|
|
||||||
- VGA now tries to emulate an S3 Trio 64 card with 2 MB
|
|
||||||
- VESA 2.0 support for some 256 color modes
|
|
||||||
- rewrote large piece of video bios code for better compatibility
|
|
||||||
- added support for the not inheritance flags.
|
|
||||||
- created functions for creating child psp.
|
|
||||||
- updated errorcodes of findfirst (thanks Mirek!)
|
|
||||||
- rewrote loggingsystem to generate less warnings
|
|
||||||
- added dos protected mode interface (dpmi)
|
|
||||||
- added cdrom label support
|
|
||||||
- improved cdrom audio playing
|
|
||||||
- fixed and improved directory cache
|
|
||||||
- debugger shows selector- and cpu mode info
|
|
||||||
- added SELINFO (selector information) command to debugger
|
|
||||||
- added reference counting for dos files
|
|
||||||
- added tab-completion
|
|
||||||
- added basic fpu support.
|
|
||||||
- fixed several bugs with case sensitive filesystems.
|
|
||||||
- added more shell commands and improved their behaviour.
|
|
||||||
- mouse improvements.
|
|
||||||
- real time clock improvements.
|
|
||||||
- DMA fixes.
|
|
||||||
- Improved .BAT file support.
|
|
||||||
|
|
||||||
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
|
|
||||||
- fixed fcb-parseline
|
|
||||||
- added debugger under linux/freebsd
|
|
||||||
- added debugger memory breakpoints and autolog function (heavy debug)
|
|
||||||
- added loadfix.com program that eats up memory (default 64kb)
|
|
||||||
Usage : loadfix [-option] [programname] [parameters]...
|
|
||||||
Example: loadfix mm2 (Allocates 64kb and starts executable mm2)
|
|
||||||
loadfix -32 mm2 (Allocates 32kb and starts executable mm2)
|
|
||||||
loadfix -128 (Allocates 128kb)
|
|
||||||
loadfix -f (frees all previous allocated memory)
|
|
||||||
- added echoing of characters for input function
|
|
||||||
- added support for backspace for input function
|
|
||||||
- added partial support for int10:01 set cursortype
|
|
||||||
- fixed most of the problems/bugs with character input.
|
|
||||||
- fixed allocationinfo call.(darksun series)
|
|
||||||
- improved dos support for non-existant functions
|
|
||||||
- Split screen support
|
|
||||||
- prefix 66 67 support
|
|
||||||
- rewrote timingscheme so 1000 hz timers don't cause problems anymore
|
|
||||||
- update adlib emulation
|
|
||||||
- fixed some isues with the mouse (double clicks and visible when it shouldn't be)
|
|
||||||
- improved mouse behaviour (mickey/pixel rate) and detection routines.
|
|
||||||
- basic ansi.sys support
|
|
||||||
- Disney sound system emulation
|
|
||||||
- rewrote upcase/lowcase functions so they work fine with gcc3.2
|
|
||||||
- SHELL: added rename and delete
|
|
||||||
- added support for command /C. Fixed crashes in the shell
|
|
||||||
- fixed various bugs when exiting dosbox
|
|
||||||
- fixed a bug in XMS
|
|
||||||
- fixed a bug with the joystick when pressing a button
|
|
||||||
- create nicer configfiles.
|
|
||||||
- bios_disk function improved.
|
|
||||||
- trapflag support
|
|
||||||
- improved vertical retrace timing.
|
|
||||||
- PIT Timer improvements and many bug fixes
|
|
||||||
- Many many bug fixes to the DOS subsystem
|
|
||||||
- Support for memory allocation strategy
|
|
||||||
- rewrote cpu mainloop to act more like a real cpu
|
|
||||||
|
|
||||||
0.56
|
|
||||||
- added support for a configclass/configfile
|
|
||||||
- added support for writing out the configclass into a configfile
|
|
||||||
- removed the language file and made it internal
|
|
||||||
- added support for writing the language file (will override the internal one)
|
|
||||||
- improved mousesupport
|
|
||||||
- updated readme
|
|
||||||
- support for screenshots
|
|
||||||
- some cpu-bug fixes
|
|
||||||
- dma changes
|
|
||||||
- Real Sound support
|
|
||||||
- EMM fixes and new functions.
|
|
||||||
- VGA fixes
|
|
||||||
- new wildcompare
|
|
||||||
- support for size and disktype at mount.
|
|
||||||
- added new debugger functionalities: start/trace into INTs, write processor status log,
|
|
||||||
step over rep and loop instructions, breakpoint support without using INT 03 (heavy debugging switch)
|
|
||||||
- Added more cpu instructions and changed the string operations.
|
|
||||||
- Added classes for most of the internal dos structures.
|
|
||||||
- Rewrote most of the fcb calls to use normal dos calls.
|
|
||||||
|
|
||||||
0.55
|
|
||||||
- fixed the errors/warnings in prefix_66.h and prefix_66_of.h (decimal too large becomming unsigned).
|
- fixed the errors/warnings in prefix_66.h and prefix_66_of.h (decimal too large becomming unsigned).
|
||||||
- fixed compilation error on FreeBSD when #disable_joystick was defined
|
|
||||||
- int10_writechar has been updated to move the cursor position.
|
|
||||||
- changed the basedir routines to use the current working dir instead of argv[0]. This will fix and brake things :)
|
|
||||||
- illegal command, now displays the command
|
|
||||||
- wildcmp updated to be case insensitive
|
|
||||||
- added fcb:open,close,findfirst, findnext.
|
|
||||||
- fixed rename in drive_local
|
|
||||||
- added new features to the debugger: breakpoint support / data view / command line
|
|
||||||
- partial support of list of lists (dos info block)
|
|
||||||
- full emm 3.2 support
|
|
||||||
- partial emm 4.0 support
|
|
||||||
- fixes to graphics core fonts (text in sierra games is now correct)
|
|
||||||
- improved support for user mousehandlers
|
|
||||||
- fixed EGA graphics
|
|
||||||
- fixed VGA graphics
|
|
||||||
- fixed write with size 0
|
|
||||||
- changed memory management.
|
|
||||||
- fixed and cleaned up the cpu flags.
|
|
||||||
- changed interrupt handler.
|
|
||||||
- speeded up the graphics.
|
|
||||||
- speeded up the cpu-core
|
|
||||||
- changed dma
|
|
||||||
- improved dma streams from emm memory
|
|
||||||
- added some cga videomodes
|
|
||||||
- added more funtions to the keyboard handler
|
|
||||||
|
93
INSTALL
93
INSTALL
@ -1,97 +1,36 @@
|
|||||||
|
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.
|
Things needed for compilation.
|
||||||
|
|
||||||
SDL
|
SDL
|
||||||
The Simple DirectMedia Library available at http://www.libsdl.org
|
The Simple DirectMedia Library available at http://www.libsdl.org
|
||||||
The dll distributed with the windows version of DOSBox is slightly
|
|
||||||
modified. You can find the changes in the sourcepackage of DOSBox
|
|
||||||
(src/platform/sdl-win32.diff). If you want the patched sourcetree
|
|
||||||
send us an email. (see README)
|
|
||||||
Licensed under LGPL
|
|
||||||
|
|
||||||
Curses (optional)
|
Curses
|
||||||
If you want to enable the debugger you need a curses library.
|
If you want to enable the debugger you need a curses library.
|
||||||
ncurses should be installed on just about every unix distro.
|
ncurses should be installed on just about every unix distro.
|
||||||
For win32 get pdcurses at http://pdcurses.sourceforge.net
|
For win32 get pdcurses at http://pdcurses.sourceforge.net
|
||||||
License: Open source
|
|
||||||
|
|
||||||
Libpng (optional)
|
|
||||||
Needed for the screenshots.
|
|
||||||
For win32 get libpng from http://gnuwin32.sourceforge.net/packages.html
|
|
||||||
See http://www.libpng.org/pub/png/ for more details.
|
|
||||||
License: Open Source
|
|
||||||
|
|
||||||
Zlib (optional)
|
|
||||||
Needed by libpng.
|
|
||||||
For win32 get libz (rename to zlib) from http://gnuwin32.sourceforge.net/packages.html
|
|
||||||
See http://www.zlib.net for more details.
|
|
||||||
License: Open Source
|
|
||||||
|
|
||||||
SDL_Net (optional)
|
|
||||||
For modem/ipx support. Get it from http://www.libsdl.org/projects/SDL_net/
|
|
||||||
Licensed under LGPL
|
|
||||||
|
|
||||||
SDL_Sound
|
|
||||||
For compressed audio on diskimages. (optional)
|
|
||||||
This is for cue/bin cdrom images with compressed (mp3/ogg) audio tracks.
|
|
||||||
Get it from http://icculus.org/SDL_sound
|
|
||||||
Licenced under LGPL
|
|
||||||
|
|
||||||
ALSA_Headers
|
|
||||||
(optional)
|
|
||||||
for Alsa support under linux. Part of the linux kernel sources
|
|
||||||
Licensed under LGPL
|
|
||||||
|
|
||||||
If you want compile from the CVS under a unix system, you'll also need
|
If you want compile from the CVS under a unix system, you'll also need
|
||||||
automake (>=1.6), autoconf(>=2.50). Should be available at http://www.gnu.org
|
automake, autoconf. Should be available at http://www.gnu.org
|
||||||
|
|
||||||
For building on unix systems.
|
For building on unix systems.
|
||||||
If you are building from the cvs run ./autogen.sh first before doing the following.
|
If you are building from the cvs run ./autogen.sh first before doing the following.
|
||||||
|
|
||||||
1. ./configure
|
1. ./configure
|
||||||
2. make
|
2. Check settings.h for some setup options.
|
||||||
|
3. make
|
||||||
|
|
||||||
In step 1 you could add the following switches:
|
Check the src subdir for the binary and dosbox.lang file.
|
||||||
--enable-debug
|
These 2 files should be in the same dir if you want to run dosbox.
|
||||||
enables the internal debugger. --enable-debug=heavy enables even more
|
|
||||||
debug options. Dosbox should then be run from a xterm and when the sdl-
|
|
||||||
window is active press alt-pause to enter the debugger.
|
|
||||||
|
|
||||||
--enable-core-inline
|
Compiling on FreeBSD might be a problem since SDL has no joystick support there.
|
||||||
enables some memory increasing inlines. This greatly increases
|
To get around this edit sdlmain.cpp to enable some #define.
|
||||||
compiletime for maybe a increase in speed.
|
Let's hope someday the sdl people will just report 0 joysticks in freebsd or get it working some other way :)
|
||||||
|
|
||||||
--disable-fpu
|
|
||||||
disables the emulated fpu. Although the fpu emulation code isn't
|
|
||||||
finished and isn't entirely accurate it's advised to leave it on.
|
|
||||||
|
|
||||||
--disable-fpu-x86
|
|
||||||
disables the assembly fpu core. Although relatively new the x86 fpu
|
|
||||||
core has more accuracy then the regular fpu core.
|
|
||||||
|
|
||||||
--disable-dynamic-x86
|
|
||||||
disables the dynamic x86 specific cpu core. Although it might be
|
|
||||||
be a bit unstable, it can greatly improve the speed of dosbox on x86
|
|
||||||
hosts.
|
|
||||||
Please note that this option on x86 will result in a different
|
|
||||||
dynamic/recompiling cpu core being compiled then the default.
|
|
||||||
For more information see the option --disable-dynrec
|
|
||||||
|
|
||||||
--disable-dynrec
|
|
||||||
disables the recompiling cpu core. Currently x86 and x86_64 only.
|
|
||||||
You can activate this core on x86 by disabling the dynamic-x86 core.
|
|
||||||
|
|
||||||
--disable-dynamic-core
|
|
||||||
disables all dynamic cores. (same effect as
|
|
||||||
--disable-dynamic-x86 --disable-dynrec)
|
|
||||||
|
|
||||||
--disable-unaligned-memory
|
|
||||||
disables unaligned memory access.
|
|
||||||
|
|
||||||
Check the src subdir for the binary.
|
|
||||||
|
|
||||||
NOTE: If capslock and numlock appear to be broken. open
|
|
||||||
src/ints/bios_keyboard.cpp and go to line 30 and read there how to fix it.
|
|
||||||
|
|
||||||
|
|
||||||
Build instructions for VC++6
|
Build instructions for VC++6
|
||||||
Don't use VC++ 6:it creates faulty code in core_normal.cpp
|
|
||||||
|
Open the workspace in the visualc subdir and build from there.
|
||||||
|
Copy the src/dosbox.lang file to the same dir as your executable.
|
||||||
|
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
# Main Makefile for DOSBox
|
# Main Makefile for DOSBox
|
||||||
|
|
||||||
EXTRA_DIST = autogen.sh
|
EXTRA_DIST = settings.h autogen.sh
|
||||||
SUBDIRS = src include docs visualc_net
|
SUBDIRS = src include visualc
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
428
Makefile.in
Normal file
428
Makefile.in
Normal file
@ -0,0 +1,428 @@
|
|||||||
|
# Makefile.in generated by automake 1.6.1 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_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@
|
||||||
|
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@
|
||||||
|
|
||||||
|
EXTRA_DIST = settings.h autogen.sh
|
||||||
|
SUBDIRS = src include visualc
|
||||||
|
subdir = .
|
||||||
|
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||||
|
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||||
|
CONFIG_HEADER = config.h
|
||||||
|
CONFIG_CLEAN_FILES =
|
||||||
|
DIST_SOURCES =
|
||||||
|
|
||||||
|
RECURSIVE_TARGETS = info-recursive dvi-recursive install-info-recursive \
|
||||||
|
uninstall-info-recursive all-recursive install-data-recursive \
|
||||||
|
install-exec-recursive installdirs-recursive install-recursive \
|
||||||
|
uninstall-recursive check-recursive installcheck-recursive
|
||||||
|
DIST_COMMON = README AUTHORS COPYING ChangeLog INSTALL Makefile.am \
|
||||||
|
Makefile.in NEWS THANKS acinclude.m4 aclocal.m4 config.guess \
|
||||||
|
config.h.in config.sub configure configure.in depcomp \
|
||||||
|
install-sh missing mkinstalldirs
|
||||||
|
DIST_SUBDIRS = $(SUBDIRS)
|
||||||
|
all: config.h
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) all-recursive
|
||||||
|
|
||||||
|
.SUFFIXES:
|
||||||
|
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
|
||||||
|
cd $(top_srcdir) && \
|
||||||
|
$(AUTOMAKE) --gnits Makefile
|
||||||
|
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||||
|
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)
|
||||||
|
|
||||||
|
$(top_builddir)/config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||||
|
$(SHELL) ./config.status --recheck
|
||||||
|
$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
|
||||||
|
cd $(srcdir) && $(AUTOCONF)
|
||||||
|
|
||||||
|
$(ACLOCAL_M4): configure.in acinclude.m4
|
||||||
|
cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
|
||||||
|
|
||||||
|
config.h: stamp-h1
|
||||||
|
@if test ! -f $@; then \
|
||||||
|
rm -f stamp-h1; \
|
||||||
|
$(MAKE) stamp-h1; \
|
||||||
|
else :; fi
|
||||||
|
|
||||||
|
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
|
||||||
|
@rm -f stamp-h1
|
||||||
|
cd $(top_builddir) && $(SHELL) ./config.status config.h
|
||||||
|
|
||||||
|
$(srcdir)/config.h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4)
|
||||||
|
cd $(top_srcdir) && $(AUTOHEADER)
|
||||||
|
touch $(srcdir)/config.h.in
|
||||||
|
|
||||||
|
distclean-hdr:
|
||||||
|
-rm -f config.h
|
||||||
|
uninstall-info-am:
|
||||||
|
|
||||||
|
# This directory's subdirectories are mostly independent; you can cd
|
||||||
|
# into them and run `make' without going through this Makefile.
|
||||||
|
# To change the values of `make' variables: instead of editing Makefiles,
|
||||||
|
# (1) if the variable is set in `config.status', edit `config.status'
|
||||||
|
# (which will cause the Makefiles to be regenerated when you run `make');
|
||||||
|
# (2) otherwise, pass the desired values on the `make' command line.
|
||||||
|
$(RECURSIVE_TARGETS):
|
||||||
|
@set fnord $$MAKEFLAGS; amf=$$2; \
|
||||||
|
dot_seen=no; \
|
||||||
|
target=`echo $@ | sed s/-recursive//`; \
|
||||||
|
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||||
|
echo "Making $$target in $$subdir"; \
|
||||||
|
if test "$$subdir" = "."; then \
|
||||||
|
dot_seen=yes; \
|
||||||
|
local_target="$$target-am"; \
|
||||||
|
else \
|
||||||
|
local_target="$$target"; \
|
||||||
|
fi; \
|
||||||
|
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|
||||||
|
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
|
||||||
|
done; \
|
||||||
|
if test "$$dot_seen" = "no"; then \
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
|
||||||
|
fi; test -z "$$fail"
|
||||||
|
|
||||||
|
mostlyclean-recursive clean-recursive distclean-recursive \
|
||||||
|
maintainer-clean-recursive:
|
||||||
|
@set fnord $$MAKEFLAGS; amf=$$2; \
|
||||||
|
dot_seen=no; \
|
||||||
|
case "$@" in \
|
||||||
|
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
|
||||||
|
*) list='$(SUBDIRS)' ;; \
|
||||||
|
esac; \
|
||||||
|
rev=''; for subdir in $$list; do \
|
||||||
|
if test "$$subdir" = "."; then :; else \
|
||||||
|
rev="$$subdir $$rev"; \
|
||||||
|
fi; \
|
||||||
|
done; \
|
||||||
|
rev="$$rev ."; \
|
||||||
|
target=`echo $@ | sed s/-recursive//`; \
|
||||||
|
for subdir in $$rev; do \
|
||||||
|
echo "Making $$target in $$subdir"; \
|
||||||
|
if test "$$subdir" = "."; then \
|
||||||
|
local_target="$$target-am"; \
|
||||||
|
else \
|
||||||
|
local_target="$$target"; \
|
||||||
|
fi; \
|
||||||
|
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|
||||||
|
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
|
||||||
|
done && test -z "$$fail"
|
||||||
|
tags-recursive:
|
||||||
|
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||||
|
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
|
||||||
|
done
|
||||||
|
|
||||||
|
ETAGS = etags
|
||||||
|
ETAGSFLAGS =
|
||||||
|
|
||||||
|
tags: TAGS
|
||||||
|
|
||||||
|
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||||
|
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||||
|
unique=`for i in $$list; do \
|
||||||
|
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||||
|
done | \
|
||||||
|
$(AWK) ' { files[$$0] = 1; } \
|
||||||
|
END { for (i in files) print i; }'`; \
|
||||||
|
mkid -fID $$unique
|
||||||
|
|
||||||
|
TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
|
||||||
|
$(TAGS_FILES) $(LISP)
|
||||||
|
tags=; \
|
||||||
|
here=`pwd`; \
|
||||||
|
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||||
|
if test "$$subdir" = .; then :; else \
|
||||||
|
test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
|
||||||
|
fi; \
|
||||||
|
done; \
|
||||||
|
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
|
||||||
|
unique=`for i in $$list; do \
|
||||||
|
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||||
|
done | \
|
||||||
|
$(AWK) ' { files[$$0] = 1; } \
|
||||||
|
END { for (i in files) print i; }'`; \
|
||||||
|
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|
||||||
|
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||||
|
$$tags $$unique
|
||||||
|
|
||||||
|
GTAGS:
|
||||||
|
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||||
|
&& cd $(top_srcdir) \
|
||||||
|
&& gtags -i $(GTAGS_ARGS) $$here
|
||||||
|
|
||||||
|
distclean-tags:
|
||||||
|
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH
|
||||||
|
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||||
|
|
||||||
|
top_distdir = .
|
||||||
|
distdir = $(PACKAGE)-$(VERSION)
|
||||||
|
|
||||||
|
am__remove_distdir = \
|
||||||
|
{ test ! -d $(distdir) \
|
||||||
|
|| { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
|
||||||
|
&& rm -fr $(distdir); }; }
|
||||||
|
|
||||||
|
GZIP_ENV = --best
|
||||||
|
distcleancheck_listfiles = find . -type f -print
|
||||||
|
|
||||||
|
distdir: $(DISTFILES)
|
||||||
|
@if sed 15q $(srcdir)/NEWS | fgrep -e "$(VERSION)" >/dev/null; \
|
||||||
|
then :; else \
|
||||||
|
echo "NEWS not updated; not releasing" 1>&2; \
|
||||||
|
exit 1; \
|
||||||
|
fi
|
||||||
|
$(am__remove_distdir)
|
||||||
|
mkdir $(distdir)
|
||||||
|
@for file in $(DISTFILES); 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
|
||||||
|
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||||
|
if test "$$subdir" = .; then :; else \
|
||||||
|
test -d $(distdir)/$$subdir \
|
||||||
|
|| mkdir $(distdir)/$$subdir \
|
||||||
|
|| exit 1; \
|
||||||
|
(cd $$subdir && \
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) \
|
||||||
|
top_distdir="$(top_distdir)" \
|
||||||
|
distdir=../$(distdir)/$$subdir \
|
||||||
|
distdir) \
|
||||||
|
|| exit 1; \
|
||||||
|
fi; \
|
||||||
|
done
|
||||||
|
-find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
|
||||||
|
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
|
||||||
|
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
|
||||||
|
! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
|
||||||
|
|| chmod -R a+r $(distdir)
|
||||||
|
dist-gzip: distdir
|
||||||
|
$(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
|
||||||
|
$(am__remove_distdir)
|
||||||
|
|
||||||
|
dist dist-all: distdir
|
||||||
|
$(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
|
||||||
|
$(am__remove_distdir)
|
||||||
|
|
||||||
|
# This target untars the dist file and tries a VPATH configuration. Then
|
||||||
|
# it guarantees that the distribution is self-contained by making another
|
||||||
|
# tarfile.
|
||||||
|
distcheck: dist
|
||||||
|
$(am__remove_distdir)
|
||||||
|
GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(AMTAR) xf -
|
||||||
|
chmod -R a-w $(distdir); chmod a+w $(distdir)
|
||||||
|
mkdir $(distdir)/=build
|
||||||
|
mkdir $(distdir)/=inst
|
||||||
|
chmod a-w $(distdir)
|
||||||
|
dc_install_base=`$(am__cd) $(distdir)/=inst && pwd` \
|
||||||
|
&& cd $(distdir)/=build \
|
||||||
|
&& ../configure --srcdir=.. --prefix=$$dc_install_base \
|
||||||
|
$(DISTCHECK_CONFIGURE_FLAGS) \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) check \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) install \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) uninstall \
|
||||||
|
&& (test `find $$dc_install_base -type f -print | wc -l` -le 1 \
|
||||||
|
|| { echo "ERROR: files left after uninstall:" ; \
|
||||||
|
find $$dc_install_base -type f -print ; \
|
||||||
|
exit 1; } >&2 ) \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) dist-gzip \
|
||||||
|
&& rm -f $(distdir).tar.gz \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck
|
||||||
|
$(am__remove_distdir)
|
||||||
|
@echo "$(distdir).tar.gz is ready for distribution" | \
|
||||||
|
sed 'h;s/./=/g;p;x;p;x'
|
||||||
|
distcleancheck: distclean
|
||||||
|
if test '$(srcdir)' = . ; then \
|
||||||
|
echo "ERROR: distcleancheck can only run from a VPATH build" ; \
|
||||||
|
exit 1 ; \
|
||||||
|
fi
|
||||||
|
test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
|
||||||
|
|| { echo "ERROR: files left after distclean:" ; \
|
||||||
|
$(distcleancheck_listfiles) ; \
|
||||||
|
exit 1; } >&2
|
||||||
|
check-am: all-am
|
||||||
|
check: check-recursive
|
||||||
|
all-am: Makefile config.h
|
||||||
|
installdirs: installdirs-recursive
|
||||||
|
installdirs-am:
|
||||||
|
|
||||||
|
install: install-recursive
|
||||||
|
install-exec: install-exec-recursive
|
||||||
|
install-data: install-data-recursive
|
||||||
|
uninstall: uninstall-recursive
|
||||||
|
|
||||||
|
install-am: all-am
|
||||||
|
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||||
|
|
||||||
|
installcheck: installcheck-recursive
|
||||||
|
install-strip:
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||||
|
INSTALL_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) stamp-h stamp-h[0-9]*
|
||||||
|
|
||||||
|
maintainer-clean-generic:
|
||||||
|
@echo "This command is intended for maintainers to use"
|
||||||
|
@echo "it deletes files that may require special tools to rebuild."
|
||||||
|
clean: clean-recursive
|
||||||
|
|
||||||
|
clean-am: clean-generic mostlyclean-am
|
||||||
|
|
||||||
|
distclean: distclean-recursive
|
||||||
|
-rm -f config.status config.cache config.log
|
||||||
|
distclean-am: clean-am distclean-generic distclean-hdr distclean-tags
|
||||||
|
|
||||||
|
dvi: dvi-recursive
|
||||||
|
|
||||||
|
dvi-am:
|
||||||
|
|
||||||
|
info: info-recursive
|
||||||
|
|
||||||
|
info-am:
|
||||||
|
|
||||||
|
install-data-am:
|
||||||
|
|
||||||
|
install-exec-am:
|
||||||
|
|
||||||
|
install-info: install-info-recursive
|
||||||
|
|
||||||
|
install-man:
|
||||||
|
|
||||||
|
installcheck-am:
|
||||||
|
|
||||||
|
maintainer-clean: maintainer-clean-recursive
|
||||||
|
|
||||||
|
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||||
|
|
||||||
|
mostlyclean: mostlyclean-recursive
|
||||||
|
|
||||||
|
mostlyclean-am: mostlyclean-generic
|
||||||
|
|
||||||
|
uninstall-am: uninstall-info-am
|
||||||
|
|
||||||
|
uninstall-info: uninstall-info-recursive
|
||||||
|
|
||||||
|
.PHONY: $(RECURSIVE_TARGETS) GTAGS all all-am check check-am clean \
|
||||||
|
clean-generic clean-recursive dist dist-all dist-gzip distcheck \
|
||||||
|
distclean distclean-generic distclean-hdr distclean-recursive \
|
||||||
|
distclean-tags distcleancheck distdir dvi dvi-am dvi-recursive \
|
||||||
|
info info-am info-recursive install install-am install-data \
|
||||||
|
install-data-am install-data-recursive install-exec \
|
||||||
|
install-exec-am install-exec-recursive install-info \
|
||||||
|
install-info-am install-info-recursive install-man \
|
||||||
|
install-recursive install-strip installcheck installcheck-am \
|
||||||
|
installdirs installdirs-am installdirs-recursive \
|
||||||
|
maintainer-clean maintainer-clean-generic \
|
||||||
|
maintainer-clean-recursive mostlyclean mostlyclean-generic \
|
||||||
|
mostlyclean-recursive tags tags-recursive uninstall \
|
||||||
|
uninstall-am uninstall-info-am uninstall-info-recursive \
|
||||||
|
uninstall-recursive
|
||||||
|
|
||||||
|
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||||
|
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||||
|
.NOEXPORT:
|
507
NEWS
507
NEWS
@ -1,510 +1,3 @@
|
|||||||
0.72
|
|
||||||
- Fixed unitialized variable in joystick. (Fixes crashes on Vista and
|
|
||||||
Mac OS X)
|
|
||||||
- Some bugfixes and speedups to the 64 bit recompiling core.
|
|
||||||
- Fixed sign flag on soundblaster dma transfers (Space Quest 6 intro)
|
|
||||||
- Fixed a bug in keyboard layout processing code and fixed certain
|
|
||||||
layouts.
|
|
||||||
- Fixed Dreamweb.
|
|
||||||
- Improved speed unlocking when running cycles=max.
|
|
||||||
- Fixed a crash related to the tab completion in the shell.
|
|
||||||
- Improved aspect correction code. Should now be like how a real monitor
|
|
||||||
handles it.
|
|
||||||
- Fixed a bug in the xms status report code. (Blake Stone 1.0 shareware)
|
|
||||||
- Added a lot more keyboard layouts.
|
|
||||||
- Fix crash related to changing the scaler before a screen was created.
|
|
||||||
- Hopefully fixed compilation on *bsd.
|
|
||||||
- Enabled auto cpu core selection for recompiling core as well.
|
|
||||||
- Made the used joystick selectable when 4axis is specified.
|
|
||||||
- Added some hints for inexperienced DOS users to the shell.
|
|
||||||
|
|
||||||
0.71
|
|
||||||
- Add a new recompiling cpu core, which should be easier to port.
|
|
||||||
- Add 64 bit version of the recompiling core.
|
|
||||||
- Add mipsel 32 bit version of the recompiling core.
|
|
||||||
- Fix a few small problems with FCBs. (fixes Jewels of darkness and
|
|
||||||
cyrus chess)
|
|
||||||
- Raise some more exceptions. (fixes vbdos)
|
|
||||||
- Fix a few problems with the dynamic core. (fixes Inner Words,
|
|
||||||
Archmimedean Dynasty and others)
|
|
||||||
- Improve/Fix fallback code for certain graphics cards.
|
|
||||||
- Fix a few cd audio related bugs.
|
|
||||||
- Add an undocumented MSCDEX feature. (Fixes Ultimate Domain)
|
|
||||||
- Fix some pcspeaker mode. (fixes Test Drive and similar games)
|
|
||||||
- Improve dos keyinput handling. (fixes Wing Commander 3 exit dialog)
|
|
||||||
- Remove Exit condition on fully nested mode. (fixes some demo)
|
|
||||||
- Add image file size detection.
|
|
||||||
- Add/Fix some ansi codes. (fixes PC Larn and certain versions of
|
|
||||||
infocom games)
|
|
||||||
- Several general DOS fixes. (fixes nba95, hexit and various other games)
|
|
||||||
- Add some valid input checks. (fixes 3d body adventure and similar
|
|
||||||
games)
|
|
||||||
- Fix digital joystick centering problem.
|
|
||||||
- Reenable textmode 54 and 55.
|
|
||||||
- Fix a pelmask problem with univbe 5.0 lite. (fixes Panzer General)
|
|
||||||
- Fix minor mixer underflow.
|
|
||||||
- Some general image and bios disk emulation fixes.
|
|
||||||
- Hopefully fix compilation on BSD and darwin.
|
|
||||||
- Try using ioctl cdrom access by default if possible.
|
|
||||||
- Fix some svga detection routine. (fixes Grandest Fleet 2 and Bobby Fischer
|
|
||||||
Teaches Chess)
|
|
||||||
- You can now close DOSBox using the status window in win32.
|
|
||||||
- Add support for NX enabled systems.
|
|
||||||
- Fix a casting error which only showed with certain compilers. (fixes
|
|
||||||
various games under mac os x and 64 bit linux)
|
|
||||||
- Improve timer and add gate 2 support. (fixes various games and
|
|
||||||
joystick problems)
|
|
||||||
- Improve mouse. Add undocumented backdoor. (fixes Last half of Darkness,
|
|
||||||
PC-BLOX and others)
|
|
||||||
- Add/improve support for ~ and ~username in all commands.
|
|
||||||
- Fix a font problem with the pcjr/tandy. (fixes personal deskmate 2)
|
|
||||||
- Change dma routine a bit. (fixes ticks in sound in various games)
|
|
||||||
- Allow read-only diskimages to be booted. (fixes various booter
|
|
||||||
games)
|
|
||||||
- Add basic hidden file support on cdrom images. (fixes Player
|
|
||||||
Manager 2)
|
|
||||||
- Add some rarely used functionality to the int10 mode setup. (fixes
|
|
||||||
WW2 Battles of the South pacific)
|
|
||||||
- Add ability to force scaler usage.
|
|
||||||
- Speed up flag generation and make it more 386-like.
|
|
||||||
- Some colourful feedback in the mapper.
|
|
||||||
- General code cleanup.
|
|
||||||
|
|
||||||
0.70
|
|
||||||
- Improve register handling and support with XMS.
|
|
||||||
- Fix some issues with deleting open files.(windows only issue)
|
|
||||||
- Add dummy LPT1 class. (windows only issue)
|
|
||||||
- Improve some of the internal dos commands. (choice, copy and shift)
|
|
||||||
- Improve ROM area. (for games that use it for random numbers or
|
|
||||||
overwrite it as some sort of detection thing)
|
|
||||||
- Improve compatibility of dynamic core by making it handle certain
|
|
||||||
pagefaults earlier.
|
|
||||||
- Move internal dos tables around so we have more umb memory.
|
|
||||||
- Add some dos tables.
|
|
||||||
- Dynamic core supports io exceptions.
|
|
||||||
- Move some interrupt handlers to XT Bios locations.
|
|
||||||
- Add a dynamic fpu on x86.
|
|
||||||
- Improve fpu on non-x86.
|
|
||||||
- Trapflag gets strict priority over hardware IRQs.
|
|
||||||
- Trapflag support for the dynamic core.
|
|
||||||
- Add dummy TRx handling.
|
|
||||||
- Fix a few rarely used character functions.
|
|
||||||
- Improve auto cycle guessing code.
|
|
||||||
- Improve and extend the joystick support.
|
|
||||||
- Add autofire support.
|
|
||||||
- Improve the mapper so you can map keys to the joystick and vice versa.
|
|
||||||
- A few game specific video card fixes.
|
|
||||||
- Fix some 64 bit cpu bugs.
|
|
||||||
- Add support for certain cdrom detection schemes.
|
|
||||||
- Improve HSG/Red Book support.
|
|
||||||
- Improve MSCDEX.
|
|
||||||
- Improve dynamic core support under intel macs.
|
|
||||||
- Add basic support for clipper programs.
|
|
||||||
- Add support for different keyboard layouts.
|
|
||||||
- Add auto core guessing.
|
|
||||||
- Fix a few flags bugs.
|
|
||||||
- Fix a few small cpu bugs.
|
|
||||||
- Improve soundblaster detection rate by various programs.
|
|
||||||
- Improve EMS emulation. (allow mapping of non standard regions)
|
|
||||||
- Improve keyboard input codes on various OS-es.
|
|
||||||
- Fix problems with filenames having stackdata in them.
|
|
||||||
- Changed a few basic operations in DOSBox so they take emulated time.
|
|
||||||
- Improve dos ioctl functions.
|
|
||||||
- Extend cpu core so they are capable of detecting and raising a few
|
|
||||||
more exception types.
|
|
||||||
- Improve DOS functions when dealing with virtual drive.
|
|
||||||
- Improve FAT drives.
|
|
||||||
- Better handling of volume-labels in file functions.
|
|
||||||
- Image disk cycling capability. (prompt)
|
|
||||||
- Try to reduce the impact of using an analog joystick.
|
|
||||||
- Several measures to avoid code invalidation on certain types
|
|
||||||
of self modification in the dynamic core.
|
|
||||||
- Add dynamic core memory function inlining.
|
|
||||||
- A few small mouse improvements. (some games are using things they
|
|
||||||
shouldn't)
|
|
||||||
- Add nullmodem emulation.(h-a-l-9000)
|
|
||||||
- Some small cga and hercules fixes.
|
|
||||||
- Add more scalers (hq2x/hq3x/sai). (Kronuz)
|
|
||||||
- Change configuration file loading support. It now supports
|
|
||||||
multiple configuration files.
|
|
||||||
- Make dynamic core capable of running some win32s programs.
|
|
||||||
- Fix and add some rare soundblaster modes. (Srecko)
|
|
||||||
- Better soundblaster mixer controls. (Srecko)
|
|
||||||
- Make soundblaster installation under windows much easier.
|
|
||||||
- Add device control channel handling.
|
|
||||||
- GEMMIS support (ems under windows).
|
|
||||||
- Support more colours in win 3. (vasyl)
|
|
||||||
- Don't show unmounted drives in windows filemanager.
|
|
||||||
- Fix some bugs in the int13 handler.
|
|
||||||
- Simulate some side-effects of bios interrupt handlers on flags.
|
|
||||||
- Add IPX functions needed by netbios.
|
|
||||||
- Make ports take emulated time.
|
|
||||||
- Tabcompletion is now aware of the CD command.
|
|
||||||
- Add suppport for the dac pel mask.
|
|
||||||
- Fixes to hercules emulation, better detection and bank switching.
|
|
||||||
- Fixes to tandy emulation, 640x200x16 mode and different sizes bank.
|
|
||||||
- EGA/VGA memory changes detection for faster rendering.
|
|
||||||
- Gus 16 bit fixes.
|
|
||||||
- Many timer improvements.
|
|
||||||
- Some pcjr fixes.
|
|
||||||
- Some booter fixes.
|
|
||||||
- Many small fixes.
|
|
||||||
|
|
||||||
0.65
|
|
||||||
- Fixed FAT writing.
|
|
||||||
- Added some more missing DOS functions.
|
|
||||||
- Improved PIC so that it actually honours irq 2/9.
|
|
||||||
- Improved intelligent MPU-401 mode so that more games work with it.
|
|
||||||
- Some mouse fixes.
|
|
||||||
- Changed DMA transfers a bit so they bypass the paging tables.
|
|
||||||
- Added S3 XGA functionality.
|
|
||||||
- Improved paging so that read and write faults are handled differently.
|
|
||||||
- Rewrote exception handling a bit (no exception 0x0B with dos4gw anymore).
|
|
||||||
- Added IO exceptions in all but the dynamic core.
|
|
||||||
- Some ems improvements.
|
|
||||||
- Added midi-device selection code for the windows hosts.
|
|
||||||
- Fix crashes/segfaults related to the disabling of the pcspeaker.
|
|
||||||
- Added some more FILES=XX detection tricks.
|
|
||||||
- Fixed some vga detection schemes.
|
|
||||||
- Fixed screenshot corruption when using -noconsole in a read-only directory.
|
|
||||||
- Fix wrong scaled screenshots.
|
|
||||||
- Added some hidden file functions when using diskimages. (helps with cdrom
|
|
||||||
detection schemes)
|
|
||||||
- Fixed a bug in the mixer code, that muted the music in certain games.
|
|
||||||
- Added an assembly fpu core.
|
|
||||||
- Made the shell more flexible for batch files.
|
|
||||||
- Check for unaligned memory acces fixes hangups on ARM processors.
|
|
||||||
- Some 64 bit fixes.
|
|
||||||
- Added code to change configuration at runtime.
|
|
||||||
- Improved ADPCM emulation.
|
|
||||||
- Fixed a few cpu instructions.
|
|
||||||
- Always report vesa 2.0 and fix some colour issues with vesa games.
|
|
||||||
- Fix video mode 0x06 and 0x0a.
|
|
||||||
- Improvements to the joystick emulation. 4 buttons are supported as well.
|
|
||||||
- Add VCPI emulation for Origin games.
|
|
||||||
- Fixed a lot of things in the boot code. Most booters work now.
|
|
||||||
- Lots of improvements to the IPX emulation.
|
|
||||||
- Rewritten modem emulation. Should work with more games.
|
|
||||||
- Improvements to the dos memory managment routines.
|
|
||||||
- Add UMB (upper memory blocks) support.
|
|
||||||
- Emulate the pause key.
|
|
||||||
- Improve Composite CGA mode emulation.
|
|
||||||
- Lots of vga compatibility changes.
|
|
||||||
- Improved support for chained video modes.
|
|
||||||
- Improved mode and palette handling in cga modes.
|
|
||||||
- Mount accepts ~ now.
|
|
||||||
- Added a few of the EGA RIL functions.
|
|
||||||
- Added TandyDAC emulation.
|
|
||||||
- OS/2 support.
|
|
||||||
- Improved and speed up the dynamic cpu core.
|
|
||||||
- Fix some errors in the CD-ROM emulation layer.
|
|
||||||
- Added an automatic work-around for some graphics chipsets.
|
|
||||||
- Add PCjr support.
|
|
||||||
- Allow mousedriver to be replaced. Fixes a few games that come with their
|
|
||||||
own (internal) driver.
|
|
||||||
- Improved dynamic cpu core so it can handle pagefaults and some obscure
|
|
||||||
types of self-modifying code.
|
|
||||||
- Added -noautoexec switch to skip the contents of [autoexec] in the
|
|
||||||
configuration file.
|
|
||||||
- Improved v86 mode emulation (mainly for Strike Commander).
|
|
||||||
- Improved timer behavior.
|
|
||||||
- Improved extended keyboard support.
|
|
||||||
- Enhanced and added several DOS tables.
|
|
||||||
- Made core_full endian safe.
|
|
||||||
- Made pagefaults endian safe.
|
|
||||||
- Add support for moviecapturing
|
|
||||||
- Add support for 15/16/32 bit videomodes.
|
|
||||||
- Add some more VESA modi (4 bit).
|
|
||||||
- Add 1024x768 output.
|
|
||||||
- Changed screenrendering so it only draws changes to the screen.
|
|
||||||
- Allow remapping of the EMS page when the dma transfer was started from
|
|
||||||
the page frame
|
|
||||||
- Made EMS and DMA work together when playing from a mapped memory page.
|
|
||||||
- Renamed several configuration options, so that they are unique.
|
|
||||||
- Merged mpu and intelligent into one option.
|
|
||||||
- Merged fullfixed and fullresolution.
|
|
||||||
- Extended keys should be handled better.
|
|
||||||
- F11 and F12 work.
|
|
||||||
- Compilation fixes for various platforms.
|
|
||||||
- Fix a few crashes when giving bad input.
|
|
||||||
- Removed interp2x and added few new scalers.
|
|
||||||
- Reintroduce the lockfree mouse. (autolock=false)
|
|
||||||
- Add a larger cache for the dynamic cpu core.
|
|
||||||
- Improved soundblaster DSP, so it gets detected by creative tools.
|
|
||||||
- Lots of bugfixes.
|
|
||||||
- Even more bugfixes.
|
|
||||||
|
|
||||||
0.63
|
|
||||||
- Fixed crash with keymapper (ctrl-f1) and output=surface.
|
|
||||||
- Added unmounting.
|
|
||||||
- Fixed multiple issues with drive labels.
|
|
||||||
- Fixed most if not all FILES=XX problems.
|
|
||||||
- Added redirection in the shell.
|
|
||||||
- Fixed crashes with subst.
|
|
||||||
- Fixed multiple crashes with the drive images support.
|
|
||||||
- Added a missing fpu instruction.
|
|
||||||
- Fixed some cpu and fpu instructions.
|
|
||||||
- Fixed a small bug related to font loading.
|
|
||||||
- Rewrote the devices support.
|
|
||||||
- Added capslock/numlock checks on startup.
|
|
||||||
- Fixed wave writing.
|
|
||||||
- A few internal DOS fixes.
|
|
||||||
- Timer fixes for the hybrid loader.
|
|
||||||
- Some small soundblaster fixes.
|
|
||||||
- The drive cache can now be cleared by a keycombo. (CTRL-F4)
|
|
||||||
- A few keyboard fixes.
|
|
||||||
- Compilation fixes on various platforms.
|
|
||||||
- Quite some debugger improvements.
|
|
||||||
- Fixed dir only showing files after the first run on cdrom drives.
|
|
||||||
- Added some cdrom detection checks.
|
|
||||||
- Enabled insert in the shell. (Easier editing of commands)
|
|
||||||
- Changed order in which executables appear with tab-completion.
|
|
||||||
- Fixed some issues with raw opl recording and using a slightly different
|
|
||||||
format
|
|
||||||
|
|
||||||
0.62
|
|
||||||
- Added blinking support in the shell and some color fixes.
|
|
||||||
- Fixed commandline parsing when .bat files involved (fixes -exit)
|
|
||||||
- Fixed issues with tabs in commandline not being processed correctly.
|
|
||||||
- Cleaned/improved shutdown sequence.
|
|
||||||
- Added some more bios functions (wait and delay functions).
|
|
||||||
- Made our XMS driver conform the specs better. (c2woody)
|
|
||||||
- Added support for some more ems functions.
|
|
||||||
- Added intelligent mpu401 emulation. (Srecko)
|
|
||||||
- Added soundblaster 16 emulation.
|
|
||||||
- Rewrote GUS emulation to sound more authentic.
|
|
||||||
- Improved pc speaker emulation.
|
|
||||||
- Added an internal (programmable) mixer.
|
|
||||||
- Added support a few soundblaster/adlib detection routines.
|
|
||||||
- Fixed lot's of bugs related to DMA transfers.
|
|
||||||
- Added interpolating prebuffering mixer routines.
|
|
||||||
- Added recording of OPL commands and raw midi.
|
|
||||||
- Fixed some bugs with the wave recording.
|
|
||||||
- Changed sensitivity settings of the mouse.
|
|
||||||
- Added ps2 mouse-emulation in bios interrupts (c2woody).
|
|
||||||
- Fixed some bugs with mouse emulation limits.
|
|
||||||
- Fixed a bug with an unterminated string in the drivelabel.
|
|
||||||
- Changed file search routines a bit to be more compatible.
|
|
||||||
- Added support for attribute-searching with fcb's.
|
|
||||||
- Added basic SDA.
|
|
||||||
- Added TPA and DIB.
|
|
||||||
- Added Lot's of missing dos tables (c2woody).
|
|
||||||
- Changed psp and dta functions to use dta.
|
|
||||||
- Returned filename in ds:dx in create-random-file (c2woody).
|
|
||||||
- Fixed a bug with date and time used on open files.
|
|
||||||
- Some mscdex fixes.
|
|
||||||
- Added the -version switch, which makes dosbox report its version.
|
|
||||||
- Added a keymapper.
|
|
||||||
- Added basic IPX emulation.
|
|
||||||
- Added cdrom iso support and floppy images support.
|
|
||||||
- Added the possibity to boot another dos version.
|
|
||||||
- Added Serial passthrough support (win32 only).
|
|
||||||
- Added the possibility to pause dosbox.
|
|
||||||
- Changed OpenGL so that it is initialized only when used.
|
|
||||||
- Make dosbox run at higher priority when active and lower when inactive.
|
|
||||||
- Added direct draw output support (win32 only).
|
|
||||||
- Added current running program to title bar.
|
|
||||||
- Rewrote video emulation to support new scalers.
|
|
||||||
- Added new graphics scalers like advmame3x,tv2x.
|
|
||||||
- Added a support for a few anti-debugger tricks.
|
|
||||||
- Improved the handling of the tab-key.
|
|
||||||
- Improved support for the numeric keyboard.
|
|
||||||
- Fixed a few cpu opcodes.
|
|
||||||
- Added cpu core simple (for lowerend machines)
|
|
||||||
- Fixed some nasty bugs in the dynamic cpu core.
|
|
||||||
- Added a few (rarely used) fpu opcodes.
|
|
||||||
- Fixed various issues with GCC 3.4.
|
|
||||||
- Many internal timer improvements (PIT and PIC).
|
|
||||||
- Added some more PIC commands (c2woody).
|
|
||||||
- Added BCD counting to the timers.
|
|
||||||
- Fix some vesa functions.
|
|
||||||
- Add some basic support for 132x25 and 132x45 textmodes.
|
|
||||||
- Improved Tandy emulation a lot.
|
|
||||||
- Lowered cpu usage when dosbox is idle.
|
|
||||||
- Allow virtualisation of some basic IO-ports (c2woody).
|
|
||||||
|
|
||||||
0.61
|
|
||||||
- Added a beta dynamic cpu for x86 hosts (very unstable)
|
|
||||||
- Added opengl and hardware overlay display output
|
|
||||||
- Rewrote the vga screen updates to go in lines
|
|
||||||
- Added paging and v86 support to cpu emulation
|
|
||||||
- Added a config option to simulate a certain type of machine
|
|
||||||
- Added hercules graphics emulation
|
|
||||||
- Made CGA/TANDY modes more compatible
|
|
||||||
- Updated textmode drawing routines to support blinking colors
|
|
||||||
- Fixed VESA set page function that was documented wrong
|
|
||||||
- Fixed some wrongly emulated cpu opcodes.
|
|
||||||
- improved exception handling
|
|
||||||
- debugger: fixes; logging of gdt,lgt,idt, new commands(Fizzban)
|
|
||||||
- fixed some mscdex issues (drive letter header error, added get directory entry)
|
|
||||||
- added/fixed some bios funcs
|
|
||||||
- added some rarely used xms functions (thanks c2woody!)
|
|
||||||
- implemented GUS emulation
|
|
||||||
- Added 16-bit DMA support (for GUS and eventually SB16)
|
|
||||||
- Fixed many small bugs in filehandling routines
|
|
||||||
- Many small FPU fixes (c2woody/Fizzban)
|
|
||||||
- Some keyboard improvements (pharlab games)
|
|
||||||
- Some Timer and cmos/rtc fixes (Mirek/Srecko/Others)
|
|
||||||
- Lot's of mouse fixes (Help from various people)
|
|
||||||
- Enabled internal modem
|
|
||||||
- Made the DOS parsing routines a bit more flexible
|
|
||||||
- Added Subst (Srecko)
|
|
||||||
- Added cdrom ioctl support for linux (prompt)
|
|
||||||
- Many internal DOS fixes: memory/files/datastructures.
|
|
||||||
- Got some help from c2woody in allowing more than 1 irq being served
|
|
||||||
- Disabled DPMI (not needed anymore. DOSBox handles almost every extender)
|
|
||||||
- Search configfile in $HOME directory if none present in current directory
|
|
||||||
- Added another way to switch to protected mode. (Thanks Morten Eriksen!)
|
|
||||||
- Fixed some odd badly documented behaviour with PSP/DTA
|
|
||||||
- Added some warnings on opening of readonly files in writemode(DOS default).
|
|
||||||
- Many shell enhanchements
|
|
||||||
- Fixed a win32 specific bug dealing with filenames starting with a "."
|
|
||||||
- Fixed some bugs with the directory structure: not found/can't save errors
|
|
||||||
|
|
||||||
0.60
|
|
||||||
- rewrote memory system for future paging support
|
|
||||||
- fixed several EMS and XMS bugs and rewrite for new memory system
|
|
||||||
- added some support for tandy video modes
|
|
||||||
- added MAME Tandy 3 voice emulation
|
|
||||||
- added MAME CMS/GameBlaster emulation
|
|
||||||
- added serial port emulation with virtual tcp/ip modem (somewhat buggy)
|
|
||||||
- sound blaster emulation is now sb pro 2.0 compatible
|
|
||||||
- added basic support for 32-bit protected mode
|
|
||||||
- VGA now tries to emulate an S3 Trio 64 card with 2 MB
|
|
||||||
- VESA 2.0 support for some 256 color modes
|
|
||||||
- rewrote large piece of video bios code for better compatibility
|
|
||||||
- added support for the not inheritance flags.
|
|
||||||
- created functions for creating child psp.
|
|
||||||
- updated errorcodes of findfirst (thanks Mirek!)
|
|
||||||
- rewrote loggingsystem to generate less warnings
|
|
||||||
- added dos protected mode interface (dpmi)
|
|
||||||
- added cdrom label support
|
|
||||||
- improved cdrom audio playing
|
|
||||||
- fixed and improved directory cache
|
|
||||||
- debugger shows selector- and cpu mode info
|
|
||||||
- added SELINFO (selector information) command to debugger
|
|
||||||
- added reference counting for dos files
|
|
||||||
- added tab-completion
|
|
||||||
- added basic fpu support.
|
|
||||||
- fixed several bugs with case sensitive filesystems.
|
|
||||||
- added more shell commands and improved their behaviour.
|
|
||||||
- mouse improvements.
|
|
||||||
- real time clock improvements.
|
|
||||||
- DMA fixes.
|
|
||||||
- Improved .BAT file support.
|
|
||||||
|
|
||||||
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
|
|
||||||
- fixed fcb-parseline
|
|
||||||
- added debugger under linux/freebsd
|
|
||||||
- added debugger memory breakpoints and autolog function (heavy debug)
|
|
||||||
- added loadfix.com program that eats up memory (default 64kb)
|
|
||||||
Usage : loadfix [-option] [programname] [parameters]...
|
|
||||||
Example: loadfix mm2 (Allocates 64kb and starts executable mm2)
|
|
||||||
loadfix -32 mm2 (Allocates 32kb and starts executable mm2)
|
|
||||||
loadfix -128 (Allocates 128kb)
|
|
||||||
loadfix -f (frees all previous allocated memory)
|
|
||||||
- added echoing of characters for input function
|
|
||||||
- added support for backspace for input function
|
|
||||||
- added partial support for int10:01 set cursortype
|
|
||||||
- fixed most of the problems/bugs with character input.
|
|
||||||
- fixed allocationinfo call.(darksun series)
|
|
||||||
- improved dos support for non-existant functions
|
|
||||||
- Split screen support
|
|
||||||
- prefix 66 67 support
|
|
||||||
- rewrote timingscheme so 1000 hz timers don't cause problems anymore
|
|
||||||
- update adlib emulation
|
|
||||||
- fixed some isues with the mouse (double clicks and visible when it shouldn't be)
|
|
||||||
- improved mouse behaviour (mickey/pixel rate) and detection routines.
|
|
||||||
- basic ansi.sys support
|
|
||||||
- Disney sound system emulation
|
|
||||||
- rewrote upcase/lowcase functions so they work fine with gcc3.2
|
|
||||||
- SHELL: added rename and delete
|
|
||||||
- added support for command /C. Fixed crashes in the shell
|
|
||||||
- fixed various bugs when exiting dosbox
|
|
||||||
- fixed a bug in XMS
|
|
||||||
- fixed a bug with the joystick when pressing a button
|
|
||||||
- create nicer configfiles.
|
|
||||||
- bios_disk function improved.
|
|
||||||
- trapflag support
|
|
||||||
- improved vertical retrace timing.
|
|
||||||
- PIT Timer improvements and many bug fixes
|
|
||||||
- Many many bug fixes to the DOS subsystem
|
|
||||||
- Support for memory allocation strategy
|
|
||||||
- rewrote cpu mainloop to act more like a real cpu
|
|
||||||
|
|
||||||
0.56
|
|
||||||
- added support for a configclass/configfile
|
|
||||||
- added support for writing out the configclass into a configfile
|
|
||||||
- removed the language file and made it internal
|
|
||||||
- added support for writing the language file (will override the internal one)
|
|
||||||
- improved mousesupport
|
|
||||||
- updated readme
|
|
||||||
- support for screenshots
|
|
||||||
- some cpu-bug fixes
|
|
||||||
- dma changes
|
|
||||||
- Real Sound support
|
|
||||||
- EMM fixes and new functions.
|
|
||||||
- VGA fixes
|
|
||||||
- new wildcompare
|
|
||||||
- support for size and disktype at mount.
|
|
||||||
- added new debugger functionalities: start/trace into INTs, write processor status log,
|
|
||||||
step over rep and loop instructions, breakpoint support without using INT 03 (heavy debugging switch)
|
|
||||||
- Added more cpu instructions and changed the string operations.
|
|
||||||
- Added classes for most of the internal dos structures.
|
|
||||||
- Rewrote most of the fcb calls to use normal dos calls.
|
|
||||||
|
|
||||||
0.55
|
|
||||||
- fixed the errors/warnings in prefix_66.h and prefix_66_of.h (decimal too large becomming unsigned).
|
|
||||||
- fixed compilation error on FreeBSD when #disable_joystick was defined
|
|
||||||
- int10_writechar has been updated to move the cursor position.
|
|
||||||
- changed the basedir routines to use the current working dir instead of argv[0]. This will fix and brake things :)
|
|
||||||
- illegal command, now displays the command
|
|
||||||
- wildcmp updated to be case insensitive
|
|
||||||
- added fcb:open,close,findfirst, findnext.
|
|
||||||
- fixed rename in drive_local
|
|
||||||
- added new features to the debugger: breakpoint support / data view / command line
|
|
||||||
- partial support of list of lists (dos info block)
|
|
||||||
- full emm 3.2 support
|
|
||||||
- partial emm 4.0 support
|
|
||||||
- fixes to graphics core fonts (text in sierra games is now correct)
|
|
||||||
- improved support for user mousehandlers
|
|
||||||
- fixed EGA graphics
|
|
||||||
- fixed VGA graphics
|
|
||||||
- fixed write with size 0
|
|
||||||
- changed memory management.
|
|
||||||
- fixed and cleaned up the cpu flags.
|
|
||||||
- changed interrupt handler.
|
|
||||||
- speeded up the graphics.
|
|
||||||
- speeded up the cpu-core
|
|
||||||
- changed dma
|
|
||||||
- improved dma streams from emm memory
|
|
||||||
- added some cga videomodes
|
|
||||||
- added more funtions to the keyboard handler
|
|
||||||
|
|
||||||
0.50:
|
0.50:
|
||||||
-added F3 to repeat the last typed command.
|
-added F3 to repeat the last typed command.
|
||||||
-made it possible to change the shellmessages(dosshell). so
|
-made it possible to change the shellmessages(dosshell). so
|
||||||
|
18
THANKS
18
THANKS
@ -3,24 +3,6 @@ We would like to thank:
|
|||||||
|
|
||||||
Vlad R. of the vdmsound project for excellent sound blaster info.
|
Vlad R. of the vdmsound project for excellent sound blaster info.
|
||||||
Tatsuyuki Satoh of the Mame Team for making an excellent FM emulator.
|
Tatsuyuki Satoh of the Mame Team for making an excellent FM emulator.
|
||||||
Jarek Burczynski for the new OPL emulator.
|
|
||||||
|
|
||||||
The Bochs and DOSemu projects which I used for information.
|
The Bochs and DOSemu projects which I used for information.
|
||||||
Freedos for ideas in making my shell.
|
Freedos for ideas in making my shell.
|
||||||
|
|
||||||
Pierre-Yves Gérardy for hosting the old Beta Board.
|
|
||||||
Colin Snover for hosting our forum.
|
|
||||||
|
|
||||||
Sourceforge for hosting our homepage and other development tools.
|
|
||||||
Mirek Luza, for his moderation of the forums.
|
|
||||||
eL_Pusher, DosFreak and MiniMax for their moderation of VOGONS forum.
|
|
||||||
|
|
||||||
crazyc and gulikoza for their work on the dynrec core.
|
|
||||||
|
|
||||||
Jantien for the version management.
|
|
||||||
Shawn, Johannes and Marcus for creating the MAC OS X version.
|
|
||||||
Jochen for creating the OS/2 version.
|
|
||||||
Ido Beeri for the icon.
|
|
||||||
All the people who submitted a bug.
|
All the people who submitted a bug.
|
||||||
The Beta Testers.
|
|
||||||
|
|
||||||
|
237
acinclude.m4
237
acinclude.m4
@ -1,7 +1,7 @@
|
|||||||
dnl AM_PATH_SDL([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
|
dnl AM_PATH_SDL([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
|
||||||
dnl Test for SDL, and define SDL_CFLAGS and SDL_LIBS
|
dnl Test for SDL, and define SDL_CFLAGS and SDL_LIBS
|
||||||
dnl
|
dnl
|
||||||
AC_DEFUN([AM_PATH_SDL],
|
AC_DEFUN(AM_PATH_SDL,
|
||||||
[dnl
|
[dnl
|
||||||
dnl Get the cflags and libraries from the sdl-config script
|
dnl Get the cflags and libraries from the sdl-config script
|
||||||
dnl
|
dnl
|
||||||
@ -159,238 +159,3 @@ int main (int argc, char *argv[])
|
|||||||
AC_SUBST(SDL_LIBS)
|
AC_SUBST(SDL_LIBS)
|
||||||
rm -f conf.sdltest
|
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-2007 The DOSBox Team
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Library General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
*/
|
|
||||||
])
|
|
||||||
|
|
||||||
AH_BOTTOM([#if C_ATTRIBUTE_ALWAYS_INLINE
|
|
||||||
#define INLINE inline __attribute__((always_inline))
|
|
||||||
#else
|
|
||||||
#define INLINE inline
|
|
||||||
#endif])
|
|
||||||
|
|
||||||
AH_BOTTOM([#if C_ATTRIBUTE_FASTCALL
|
|
||||||
#define DB_FASTCALL __attribute__((fastcall))
|
|
||||||
#else
|
|
||||||
#define DB_FASTCALL
|
|
||||||
#endif])
|
|
||||||
|
|
||||||
|
|
||||||
AH_BOTTOM([#if C_HAS_ATTRIBUTE
|
|
||||||
#define GCC_ATTRIBUTE(x) __attribute__ ((x))
|
|
||||||
#else
|
|
||||||
#define GCC_ATTRIBUTE(x) /* attribute not supported */
|
|
||||||
#endif])
|
|
||||||
|
|
||||||
AH_BOTTOM([#if C_HAS_BUILTIN_EXPECT
|
|
||||||
#define GCC_UNLIKELY(x) __builtin_expect((x),0)
|
|
||||||
#else
|
|
||||||
#define GCC_UNLIKELY(x) (x)
|
|
||||||
#endif])
|
|
||||||
|
|
||||||
AH_BOTTOM([
|
|
||||||
typedef double Real64;
|
|
||||||
|
|
||||||
#if SIZEOF_UNSIGNED_CHAR != 1
|
|
||||||
# error "sizeof (unsigned char) != 1"
|
|
||||||
#else
|
|
||||||
typedef unsigned char Bit8u;
|
|
||||||
typedef signed char Bit8s;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if SIZEOF_UNSIGNED_SHORT != 2
|
|
||||||
# error "sizeof (unsigned short) != 2"
|
|
||||||
#else
|
|
||||||
typedef unsigned short Bit16u;
|
|
||||||
typedef signed short Bit16s;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if SIZEOF_UNSIGNED_INT == 4
|
|
||||||
typedef unsigned int Bit32u;
|
|
||||||
typedef signed int Bit32s;
|
|
||||||
#elif SIZEOF_UNSIGNED_LONG == 4
|
|
||||||
typedef unsigned long Bit32u;
|
|
||||||
typedef signed long Bit32s;
|
|
||||||
#else
|
|
||||||
# error "can't find sizeof(type) of 4 bytes!"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if SIZEOF_UNSIGNED_LONG == 8
|
|
||||||
typedef unsigned long Bit64u;
|
|
||||||
typedef signed long Bit64s;
|
|
||||||
#elif SIZEOF_UNSIGNED_LONG_LONG == 8
|
|
||||||
typedef unsigned long long Bit64u;
|
|
||||||
typedef signed long long Bit64s;
|
|
||||||
#else
|
|
||||||
# error "can't find data type of 8 bytes"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if SIZEOF_INT_P == 4
|
|
||||||
typedef Bit32u Bitu;
|
|
||||||
typedef Bit32s Bits;
|
|
||||||
#else
|
|
||||||
typedef Bit64u Bitu;
|
|
||||||
typedef Bit64s Bits;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
])
|
|
||||||
|
992
aclocal.m4
vendored
Normal file
992
aclocal.m4
vendored
Normal file
@ -0,0 +1,992 @@
|
|||||||
|
# aclocal.m4 generated automatically by aclocal 1.6.1 -*- Autoconf -*-
|
||||||
|
|
||||||
|
# Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002
|
||||||
|
# Free Software Foundation, Inc.
|
||||||
|
# This file 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.
|
||||||
|
|
||||||
|
dnl AM_PATH_SDL([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]])
|
||||||
|
dnl Test for SDL, and define SDL_CFLAGS and SDL_LIBS
|
||||||
|
dnl
|
||||||
|
AC_DEFUN(AM_PATH_SDL,
|
||||||
|
[dnl
|
||||||
|
dnl Get the cflags and libraries from the sdl-config script
|
||||||
|
dnl
|
||||||
|
AC_ARG_WITH(sdl-prefix,[ --with-sdl-prefix=PFX Prefix where SDL is installed (optional)],
|
||||||
|
sdl_prefix="$withval", sdl_prefix="")
|
||||||
|
AC_ARG_WITH(sdl-exec-prefix,[ --with-sdl-exec-prefix=PFX Exec prefix where SDL is installed (optional)],
|
||||||
|
sdl_exec_prefix="$withval", sdl_exec_prefix="")
|
||||||
|
AC_ARG_ENABLE(sdltest, [ --disable-sdltest Do not try to compile and run a test SDL program],
|
||||||
|
, enable_sdltest=yes)
|
||||||
|
|
||||||
|
if test x$sdl_exec_prefix != x ; then
|
||||||
|
sdl_args="$sdl_args --exec-prefix=$sdl_exec_prefix"
|
||||||
|
if test x${SDL_CONFIG+set} != xset ; then
|
||||||
|
SDL_CONFIG=$sdl_exec_prefix/bin/sdl-config
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if test x$sdl_prefix != x ; then
|
||||||
|
sdl_args="$sdl_args --prefix=$sdl_prefix"
|
||||||
|
if test x${SDL_CONFIG+set} != xset ; then
|
||||||
|
SDL_CONFIG=$sdl_prefix/bin/sdl-config
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_PATH_PROG(SDL_CONFIG, sdl-config, no)
|
||||||
|
min_sdl_version=ifelse([$1], ,0.11.0,$1)
|
||||||
|
AC_MSG_CHECKING(for SDL - version >= $min_sdl_version)
|
||||||
|
no_sdl=""
|
||||||
|
if test "$SDL_CONFIG" = "no" ; then
|
||||||
|
no_sdl=yes
|
||||||
|
else
|
||||||
|
SDL_CFLAGS=`$SDL_CONFIG $sdlconf_args --cflags`
|
||||||
|
SDL_LIBS=`$SDL_CONFIG $sdlconf_args --libs`
|
||||||
|
|
||||||
|
sdl_major_version=`$SDL_CONFIG $sdl_args --version | \
|
||||||
|
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'`
|
||||||
|
sdl_minor_version=`$SDL_CONFIG $sdl_args --version | \
|
||||||
|
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'`
|
||||||
|
sdl_micro_version=`$SDL_CONFIG $sdl_config_args --version | \
|
||||||
|
sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'`
|
||||||
|
if test "x$enable_sdltest" = "xyes" ; then
|
||||||
|
ac_save_CFLAGS="$CFLAGS"
|
||||||
|
ac_save_LIBS="$LIBS"
|
||||||
|
CFLAGS="$CFLAGS $SDL_CFLAGS"
|
||||||
|
LIBS="$LIBS $SDL_LIBS"
|
||||||
|
dnl
|
||||||
|
dnl Now check if the installed SDL is sufficiently new. (Also sanity
|
||||||
|
dnl checks the results of sdl-config to some extent
|
||||||
|
dnl
|
||||||
|
rm -f conf.sdltest
|
||||||
|
AC_TRY_RUN([
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "SDL.h"
|
||||||
|
|
||||||
|
char*
|
||||||
|
my_strdup (char *str)
|
||||||
|
{
|
||||||
|
char *new_str;
|
||||||
|
|
||||||
|
if (str)
|
||||||
|
{
|
||||||
|
new_str = (char *)malloc ((strlen (str) + 1) * sizeof(char));
|
||||||
|
strcpy (new_str, str);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
new_str = NULL;
|
||||||
|
|
||||||
|
return new_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main (int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int major, minor, micro;
|
||||||
|
char *tmp_version;
|
||||||
|
|
||||||
|
/* This hangs on some systems (?)
|
||||||
|
system ("touch conf.sdltest");
|
||||||
|
*/
|
||||||
|
{ FILE *fp = fopen("conf.sdltest", "a"); if ( fp ) fclose(fp); }
|
||||||
|
|
||||||
|
/* HP/UX 9 (%@#!) writes to sscanf strings */
|
||||||
|
tmp_version = my_strdup("$min_sdl_version");
|
||||||
|
if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) {
|
||||||
|
printf("%s, bad version string\n", "$min_sdl_version");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (($sdl_major_version > major) ||
|
||||||
|
(($sdl_major_version == major) && ($sdl_minor_version > minor)) ||
|
||||||
|
(($sdl_major_version == major) && ($sdl_minor_version == minor) && ($sdl_micro_version >= micro)))
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("\n*** 'sdl-config --version' returned %d.%d.%d, but the minimum version\n", $sdl_major_version, $sdl_minor_version, $sdl_micro_version);
|
||||||
|
printf("*** of SDL required is %d.%d.%d. If sdl-config is correct, then it is\n", major, minor, micro);
|
||||||
|
printf("*** best to upgrade to the required version.\n");
|
||||||
|
printf("*** If sdl-config was wrong, set the environment variable SDL_CONFIG\n");
|
||||||
|
printf("*** to point to the correct copy of sdl-config, and remove the file\n");
|
||||||
|
printf("*** config.cache before re-running configure\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
],, no_sdl=yes,[echo $ac_n "cross compiling; assumed OK... $ac_c"])
|
||||||
|
CFLAGS="$ac_save_CFLAGS"
|
||||||
|
LIBS="$ac_save_LIBS"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
if test "x$no_sdl" = x ; then
|
||||||
|
AC_MSG_RESULT(yes)
|
||||||
|
ifelse([$2], , :, [$2])
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT(no)
|
||||||
|
if test "$SDL_CONFIG" = "no" ; then
|
||||||
|
echo "*** The sdl-config script installed by SDL could not be found"
|
||||||
|
echo "*** If SDL was installed in PREFIX, make sure PREFIX/bin is in"
|
||||||
|
echo "*** your path, or set the SDL_CONFIG environment variable to the"
|
||||||
|
echo "*** full path to sdl-config."
|
||||||
|
else
|
||||||
|
if test -f conf.sdltest ; then
|
||||||
|
:
|
||||||
|
else
|
||||||
|
echo "*** Could not run SDL test program, checking why..."
|
||||||
|
CFLAGS="$CFLAGS $SDL_CFLAGS"
|
||||||
|
LIBS="$LIBS $SDL_LIBS"
|
||||||
|
AC_TRY_LINK([
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "SDL.h"
|
||||||
|
], [ return 0; ],
|
||||||
|
[ echo "*** The test program compiled, but did not run. This usually means"
|
||||||
|
echo "*** that the run-time linker is not finding SDL or finding the wrong"
|
||||||
|
echo "*** version of SDL. If it is not finding SDL, you'll need to set your"
|
||||||
|
echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
|
||||||
|
echo "*** to the installed location Also, make sure you have run ldconfig if that"
|
||||||
|
echo "*** is required on your system"
|
||||||
|
echo "***"
|
||||||
|
echo "*** If you have an old version installed, it is best to remove it, although"
|
||||||
|
echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH"],
|
||||||
|
[ echo "*** The test program failed to compile or link. See the file config.log for the"
|
||||||
|
echo "*** exact error that occured. This usually means SDL was incorrectly installed"
|
||||||
|
echo "*** or that you have moved SDL since it was installed. In the latter case, you"
|
||||||
|
echo "*** may want to edit the sdl-config script: $SDL_CONFIG" ])
|
||||||
|
CFLAGS="$ac_save_CFLAGS"
|
||||||
|
LIBS="$ac_save_LIBS"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
SDL_CFLAGS=""
|
||||||
|
SDL_LIBS=""
|
||||||
|
ifelse([$3], , :, [$3])
|
||||||
|
fi
|
||||||
|
AC_SUBST(SDL_CFLAGS)
|
||||||
|
AC_SUBST(SDL_LIBS)
|
||||||
|
rm -f conf.sdltest
|
||||||
|
])
|
||||||
|
|
||||||
|
# Do all the work for Automake. -*- Autoconf -*-
|
||||||
|
|
||||||
|
# This macro actually does too much some checks are only needed if
|
||||||
|
# your package does certain things. But this isn't really a big deal.
|
||||||
|
|
||||||
|
# Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002
|
||||||
|
# Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
# 02111-1307, USA.
|
||||||
|
|
||||||
|
# serial 8
|
||||||
|
|
||||||
|
# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
|
||||||
|
# written in clear, in which case automake, when reading aclocal.m4,
|
||||||
|
# will think it sees a *use*, and therefore will trigger all it's
|
||||||
|
# C support machinery. Also note that it means that autoscan, seeing
|
||||||
|
# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
|
||||||
|
|
||||||
|
|
||||||
|
AC_PREREQ([2.52])
|
||||||
|
|
||||||
|
# Autoconf 2.50 wants to disallow AM_ names. We explicitly allow
|
||||||
|
# the ones we care about.
|
||||||
|
m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
|
||||||
|
|
||||||
|
# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
|
||||||
|
# AM_INIT_AUTOMAKE([OPTIONS])
|
||||||
|
# -----------------------------------------------
|
||||||
|
# The call with PACKAGE and VERSION arguments is the old style
|
||||||
|
# call (pre autoconf-2.50), which is being phased out. PACKAGE
|
||||||
|
# and VERSION should now be passed to AC_INIT and removed from
|
||||||
|
# the call to AM_INIT_AUTOMAKE.
|
||||||
|
# We support both call styles for the transition. After
|
||||||
|
# the next Automake release, Autoconf can make the AC_INIT
|
||||||
|
# arguments mandatory, and then we can depend on a new Autoconf
|
||||||
|
# release and drop the old call support.
|
||||||
|
AC_DEFUN([AM_INIT_AUTOMAKE],
|
||||||
|
[AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
|
||||||
|
AC_REQUIRE([AC_PROG_INSTALL])dnl
|
||||||
|
# test to see if srcdir already configured
|
||||||
|
if test "`cd $srcdir && pwd`" != "`pwd`" &&
|
||||||
|
test -f $srcdir/config.status; then
|
||||||
|
AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Define the identity of the package.
|
||||||
|
dnl Distinguish between old-style and new-style calls.
|
||||||
|
m4_ifval([$2],
|
||||||
|
[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
|
||||||
|
AC_SUBST([PACKAGE], [$1])dnl
|
||||||
|
AC_SUBST([VERSION], [$2])],
|
||||||
|
[_AM_SET_OPTIONS([$1])dnl
|
||||||
|
AC_SUBST([PACKAGE], [AC_PACKAGE_TARNAME])dnl
|
||||||
|
AC_SUBST([VERSION], [AC_PACKAGE_VERSION])])dnl
|
||||||
|
|
||||||
|
_AM_IF_OPTION([no-define],,
|
||||||
|
[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
|
||||||
|
AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
|
||||||
|
|
||||||
|
# Some tools Automake needs.
|
||||||
|
AC_REQUIRE([AM_SANITY_CHECK])dnl
|
||||||
|
AC_REQUIRE([AC_ARG_PROGRAM])dnl
|
||||||
|
AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
|
||||||
|
AM_MISSING_PROG(AUTOCONF, autoconf)
|
||||||
|
AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
|
||||||
|
AM_MISSING_PROG(AUTOHEADER, autoheader)
|
||||||
|
AM_MISSING_PROG(MAKEINFO, makeinfo)
|
||||||
|
AM_MISSING_PROG(AMTAR, tar)
|
||||||
|
AM_PROG_INSTALL_SH
|
||||||
|
AM_PROG_INSTALL_STRIP
|
||||||
|
# We need awk for the "check" target. The system "awk" is bad on
|
||||||
|
# some platforms.
|
||||||
|
AC_REQUIRE([AC_PROG_AWK])dnl
|
||||||
|
AC_REQUIRE([AC_PROG_MAKE_SET])dnl
|
||||||
|
|
||||||
|
_AM_IF_OPTION([no-dependencies],,
|
||||||
|
[AC_PROVIDE_IFELSE([AC_PROG_][CC],
|
||||||
|
[_AM_DEPENDENCIES(CC)],
|
||||||
|
[define([AC_PROG_][CC],
|
||||||
|
defn([AC_PROG_][CC])[_AM_DEPENDENCIES(CC)])])dnl
|
||||||
|
AC_PROVIDE_IFELSE([AC_PROG_][CXX],
|
||||||
|
[_AM_DEPENDENCIES(CXX)],
|
||||||
|
[define([AC_PROG_][CXX],
|
||||||
|
defn([AC_PROG_][CXX])[_AM_DEPENDENCIES(CXX)])])dnl
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|
||||||
|
# Copyright 2002 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
|
||||||
|
# AM_AUTOMAKE_VERSION(VERSION)
|
||||||
|
# ----------------------------
|
||||||
|
# Automake X.Y traces this macro to ensure aclocal.m4 has been
|
||||||
|
# generated from the m4 files accompanying Automake X.Y.
|
||||||
|
AC_DEFUN([AM_AUTOMAKE_VERSION],[am__api_version="1.6"])
|
||||||
|
|
||||||
|
# AM_SET_CURRENT_AUTOMAKE_VERSION
|
||||||
|
# -------------------------------
|
||||||
|
# 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])])
|
||||||
|
|
||||||
|
# Helper functions for option handling. -*- Autoconf -*-
|
||||||
|
|
||||||
|
# Copyright 2001, 2002 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
# 02111-1307, USA.
|
||||||
|
|
||||||
|
# serial 2
|
||||||
|
|
||||||
|
# _AM_MANGLE_OPTION(NAME)
|
||||||
|
# -----------------------
|
||||||
|
AC_DEFUN([_AM_MANGLE_OPTION],
|
||||||
|
[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
|
||||||
|
|
||||||
|
# _AM_SET_OPTION(NAME)
|
||||||
|
# ------------------------------
|
||||||
|
# Set option NAME. Presently that only means defining a flag for this option.
|
||||||
|
AC_DEFUN([_AM_SET_OPTION],
|
||||||
|
[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
|
||||||
|
|
||||||
|
# _AM_SET_OPTIONS(OPTIONS)
|
||||||
|
# ----------------------------------
|
||||||
|
# OPTIONS is a space-separated list of Automake options.
|
||||||
|
AC_DEFUN([_AM_SET_OPTIONS],
|
||||||
|
[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
|
||||||
|
|
||||||
|
# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
|
||||||
|
# -------------------------------------------
|
||||||
|
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
|
||||||
|
AC_DEFUN([_AM_IF_OPTION],
|
||||||
|
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
|
||||||
|
|
||||||
|
#
|
||||||
|
# Check to make sure that the build environment is sane.
|
||||||
|
#
|
||||||
|
|
||||||
|
# Copyright 1996, 1997, 2000, 2001 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
# 02111-1307, USA.
|
||||||
|
|
||||||
|
# serial 3
|
||||||
|
|
||||||
|
# AM_SANITY_CHECK
|
||||||
|
# ---------------
|
||||||
|
AC_DEFUN([AM_SANITY_CHECK],
|
||||||
|
[AC_MSG_CHECKING([whether build environment is sane])
|
||||||
|
# Just in case
|
||||||
|
sleep 1
|
||||||
|
echo timestamp > conftest.file
|
||||||
|
# Do `set' in a subshell so we don't clobber the current shell's
|
||||||
|
# arguments. Must try -L first in case configure is actually a
|
||||||
|
# symlink; some systems play weird games with the mod time of symlinks
|
||||||
|
# (eg FreeBSD returns the mod time of the symlink's containing
|
||||||
|
# directory).
|
||||||
|
if (
|
||||||
|
set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
|
||||||
|
if test "$[*]" = "X"; then
|
||||||
|
# -L didn't work.
|
||||||
|
set X `ls -t $srcdir/configure conftest.file`
|
||||||
|
fi
|
||||||
|
rm -f conftest.file
|
||||||
|
if test "$[*]" != "X $srcdir/configure conftest.file" \
|
||||||
|
&& test "$[*]" != "X conftest.file $srcdir/configure"; then
|
||||||
|
|
||||||
|
# If neither matched, then we have a broken ls. This can happen
|
||||||
|
# if, for instance, CONFIG_SHELL is bash and it inherits a
|
||||||
|
# broken ls alias from the environment. This has actually
|
||||||
|
# happened. Such a system could not be considered "sane".
|
||||||
|
AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
|
||||||
|
alias in your environment])
|
||||||
|
fi
|
||||||
|
|
||||||
|
test "$[2]" = conftest.file
|
||||||
|
)
|
||||||
|
then
|
||||||
|
# Ok.
|
||||||
|
:
|
||||||
|
else
|
||||||
|
AC_MSG_ERROR([newly created file is older than distributed files!
|
||||||
|
Check your system clock])
|
||||||
|
fi
|
||||||
|
AC_MSG_RESULT(yes)])
|
||||||
|
|
||||||
|
# -*- Autoconf -*-
|
||||||
|
|
||||||
|
|
||||||
|
# Copyright 1997, 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
# 02111-1307, USA.
|
||||||
|
|
||||||
|
# serial 3
|
||||||
|
|
||||||
|
# AM_MISSING_PROG(NAME, PROGRAM)
|
||||||
|
# ------------------------------
|
||||||
|
AC_DEFUN([AM_MISSING_PROG],
|
||||||
|
[AC_REQUIRE([AM_MISSING_HAS_RUN])
|
||||||
|
$1=${$1-"${am_missing_run}$2"}
|
||||||
|
AC_SUBST($1)])
|
||||||
|
|
||||||
|
|
||||||
|
# AM_MISSING_HAS_RUN
|
||||||
|
# ------------------
|
||||||
|
# Define MISSING if not defined so far and test if it supports --run.
|
||||||
|
# If it does, set am_missing_run to use it, otherwise, to nothing.
|
||||||
|
AC_DEFUN([AM_MISSING_HAS_RUN],
|
||||||
|
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
|
||||||
|
test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
|
||||||
|
# Use eval to expand $SHELL
|
||||||
|
if eval "$MISSING --run true"; then
|
||||||
|
am_missing_run="$MISSING --run "
|
||||||
|
else
|
||||||
|
am_missing_run=
|
||||||
|
AC_MSG_WARN([`missing' script is too old or missing])
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
|
||||||
|
# AM_AUX_DIR_EXPAND
|
||||||
|
|
||||||
|
# Copyright 2001 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
# 02111-1307, USA.
|
||||||
|
|
||||||
|
# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
|
||||||
|
# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
|
||||||
|
# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
|
||||||
|
#
|
||||||
|
# Of course, Automake must honor this variable whenever it calls a
|
||||||
|
# tool from the auxiliary directory. The problem is that $srcdir (and
|
||||||
|
# therefore $ac_aux_dir as well) can be either absolute or relative,
|
||||||
|
# depending on how configure is run. This is pretty annoying, since
|
||||||
|
# it makes $ac_aux_dir quite unusable in subdirectories: in the top
|
||||||
|
# source directory, any form will work fine, but in subdirectories a
|
||||||
|
# relative path needs to be adjusted first.
|
||||||
|
#
|
||||||
|
# $ac_aux_dir/missing
|
||||||
|
# fails when called from a subdirectory if $ac_aux_dir is relative
|
||||||
|
# $top_srcdir/$ac_aux_dir/missing
|
||||||
|
# fails if $ac_aux_dir is absolute,
|
||||||
|
# fails when called from a subdirectory in a VPATH build with
|
||||||
|
# a relative $ac_aux_dir
|
||||||
|
#
|
||||||
|
# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
|
||||||
|
# are both prefixed by $srcdir. In an in-source build this is usually
|
||||||
|
# harmless because $srcdir is `.', but things will broke when you
|
||||||
|
# start a VPATH build or use an absolute $srcdir.
|
||||||
|
#
|
||||||
|
# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
|
||||||
|
# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
|
||||||
|
# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
|
||||||
|
# and then we would define $MISSING as
|
||||||
|
# MISSING="\${SHELL} $am_aux_dir/missing"
|
||||||
|
# This will work as long as MISSING is not called from configure, because
|
||||||
|
# unfortunately $(top_srcdir) has no meaning in configure.
|
||||||
|
# However there are other variables, like CC, which are often used in
|
||||||
|
# configure, and could therefore not use this "fixed" $ac_aux_dir.
|
||||||
|
#
|
||||||
|
# Another solution, used here, is to always expand $ac_aux_dir to an
|
||||||
|
# absolute PATH. The drawback is that using absolute paths prevent a
|
||||||
|
# configured tree to be moved without reconfiguration.
|
||||||
|
|
||||||
|
# Rely on autoconf to set up CDPATH properly.
|
||||||
|
AC_PREREQ([2.50])
|
||||||
|
|
||||||
|
AC_DEFUN([AM_AUX_DIR_EXPAND], [
|
||||||
|
# expand $ac_aux_dir to an absolute path
|
||||||
|
am_aux_dir=`cd $ac_aux_dir && pwd`
|
||||||
|
])
|
||||||
|
|
||||||
|
# AM_PROG_INSTALL_SH
|
||||||
|
# ------------------
|
||||||
|
# Define $install_sh.
|
||||||
|
|
||||||
|
# Copyright 2001 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
# 02111-1307, USA.
|
||||||
|
|
||||||
|
AC_DEFUN([AM_PROG_INSTALL_SH],
|
||||||
|
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
|
||||||
|
install_sh=${install_sh-"$am_aux_dir/install-sh"}
|
||||||
|
AC_SUBST(install_sh)])
|
||||||
|
|
||||||
|
# AM_PROG_INSTALL_STRIP
|
||||||
|
|
||||||
|
# Copyright 2001 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
# 02111-1307, USA.
|
||||||
|
|
||||||
|
# One issue with vendor `install' (even GNU) is that you can't
|
||||||
|
# specify the program used to strip binaries. This is especially
|
||||||
|
# annoying in cross-compiling environments, where the build's strip
|
||||||
|
# is unlikely to handle the host's binaries.
|
||||||
|
# Fortunately install-sh will honor a STRIPPROG variable, so we
|
||||||
|
# always use install-sh in `make install-strip', and initialize
|
||||||
|
# STRIPPROG with the value of the STRIP variable (set by the user).
|
||||||
|
AC_DEFUN([AM_PROG_INSTALL_STRIP],
|
||||||
|
[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
|
||||||
|
# Installed binaries are usually stripped using `strip' when the user
|
||||||
|
# run `make install-strip'. However `strip' might not be the right
|
||||||
|
# tool to use in cross-compilation environments, therefore Automake
|
||||||
|
# will honor the `STRIP' environment variable to overrule this program.
|
||||||
|
dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
|
||||||
|
if test "$cross_compiling" != no; then
|
||||||
|
AC_CHECK_TOOL([STRIP], [strip], :)
|
||||||
|
fi
|
||||||
|
INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
|
||||||
|
AC_SUBST([INSTALL_STRIP_PROGRAM])])
|
||||||
|
|
||||||
|
# serial 4 -*- Autoconf -*-
|
||||||
|
|
||||||
|
# Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
# 02111-1307, USA.
|
||||||
|
|
||||||
|
|
||||||
|
# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
|
||||||
|
# written in clear, in which case automake, when reading aclocal.m4,
|
||||||
|
# will think it sees a *use*, and therefore will trigger all it's
|
||||||
|
# C support machinery. Also note that it means that autoscan, seeing
|
||||||
|
# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# _AM_DEPENDENCIES(NAME)
|
||||||
|
# ----------------------
|
||||||
|
# See how the compiler implements dependency checking.
|
||||||
|
# NAME is "CC", "CXX", "GCJ", or "OBJC".
|
||||||
|
# We try a few techniques and use that to set a single cache variable.
|
||||||
|
#
|
||||||
|
# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
|
||||||
|
# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
|
||||||
|
# dependency, and given that the user is not expected to run this macro,
|
||||||
|
# just rely on AC_PROG_CC.
|
||||||
|
AC_DEFUN([_AM_DEPENDENCIES],
|
||||||
|
[AC_REQUIRE([AM_SET_DEPDIR])dnl
|
||||||
|
AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
|
||||||
|
AC_REQUIRE([AM_MAKE_INCLUDE])dnl
|
||||||
|
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], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
|
||||||
|
[depcc="$$1" am_compiler_list=])
|
||||||
|
|
||||||
|
AC_CACHE_CHECK([dependency style of $depcc],
|
||||||
|
[am_cv_$1_dependencies_compiler_type],
|
||||||
|
[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
|
||||||
|
# We make a subdir and do the tests there. Otherwise we can end up
|
||||||
|
# making bogus files that we don't know about and never remove. For
|
||||||
|
# instance it was reported that on HP-UX the gcc test will end up
|
||||||
|
# making a dummy file named `D' -- because `-MD' means `put the output
|
||||||
|
# in D'.
|
||||||
|
mkdir conftest.dir
|
||||||
|
# Copy depcomp to subdir because otherwise we won't find it if we're
|
||||||
|
# using a relative directory.
|
||||||
|
cp "$am_depcomp" conftest.dir
|
||||||
|
cd conftest.dir
|
||||||
|
|
||||||
|
am_cv_$1_dependencies_compiler_type=none
|
||||||
|
if test "$am_compiler_list" = ""; then
|
||||||
|
am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
|
||||||
|
fi
|
||||||
|
for depmode in $am_compiler_list; do
|
||||||
|
# We need to recreate these files for each test, as the compiler may
|
||||||
|
# overwrite some of them when testing with obscure command lines.
|
||||||
|
# This happens at least with the AIX C compiler.
|
||||||
|
echo '#include "conftest.h"' > conftest.c
|
||||||
|
echo 'int i;' > conftest.h
|
||||||
|
echo "${am__include} ${am__quote}conftest.Po${am__quote}" > confmf
|
||||||
|
|
||||||
|
case $depmode in
|
||||||
|
nosideeffect)
|
||||||
|
# after this tag, mechanisms are not by side-effect, so they'll
|
||||||
|
# only be used when explicitly requested
|
||||||
|
if test "x$enable_dependency_tracking" = xyes; then
|
||||||
|
continue
|
||||||
|
else
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
none) break ;;
|
||||||
|
esac
|
||||||
|
# We check with `-c' and `-o' for the sake of the "dashmstdout"
|
||||||
|
# mode. It turns out that the SunPro C++ compiler does not properly
|
||||||
|
# handle `-M -o', and we need to detect this.
|
||||||
|
if depmode=$depmode \
|
||||||
|
source=conftest.c object=conftest.o \
|
||||||
|
depfile=conftest.Po tmpdepfile=conftest.TPo \
|
||||||
|
$SHELL ./depcomp $depcc -c conftest.c -o conftest.o >/dev/null 2>&1 &&
|
||||||
|
grep conftest.h conftest.Po > /dev/null 2>&1 &&
|
||||||
|
${MAKE-make} -s -f confmf > /dev/null 2>&1; then
|
||||||
|
am_cv_$1_dependencies_compiler_type=$depmode
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
rm -rf conftest.dir
|
||||||
|
else
|
||||||
|
am_cv_$1_dependencies_compiler_type=none
|
||||||
|
fi
|
||||||
|
])
|
||||||
|
AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
# AM_SET_DEPDIR
|
||||||
|
# -------------
|
||||||
|
# Choose a directory name for dependency files.
|
||||||
|
# This macro is AC_REQUIREd in _AM_DEPENDENCIES
|
||||||
|
AC_DEFUN([AM_SET_DEPDIR],
|
||||||
|
[rm -f .deps 2>/dev/null
|
||||||
|
mkdir .deps 2>/dev/null
|
||||||
|
if test -d .deps; then
|
||||||
|
DEPDIR=.deps
|
||||||
|
else
|
||||||
|
# MS-DOS does not allow filenames that begin with a dot.
|
||||||
|
DEPDIR=_deps
|
||||||
|
fi
|
||||||
|
rmdir .deps 2>/dev/null
|
||||||
|
AC_SUBST([DEPDIR])
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
# AM_DEP_TRACK
|
||||||
|
# ------------
|
||||||
|
AC_DEFUN([AM_DEP_TRACK],
|
||||||
|
[AC_ARG_ENABLE(dependency-tracking,
|
||||||
|
[ --disable-dependency-tracking Speeds up one-time builds
|
||||||
|
--enable-dependency-tracking Do not reject slow dependency extractors])
|
||||||
|
if test "x$enable_dependency_tracking" != xno; then
|
||||||
|
am_depcomp="$ac_aux_dir/depcomp"
|
||||||
|
AMDEPBACKSLASH='\'
|
||||||
|
fi
|
||||||
|
AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
|
||||||
|
AC_SUBST([AMDEPBACKSLASH])
|
||||||
|
])
|
||||||
|
|
||||||
|
# Generate code to set up dependency tracking. -*- Autoconf -*-
|
||||||
|
|
||||||
|
# Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
# 02111-1307, USA.
|
||||||
|
|
||||||
|
#serial 2
|
||||||
|
|
||||||
|
# _AM_OUTPUT_DEPENDENCY_COMMANDS
|
||||||
|
# ------------------------------
|
||||||
|
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
|
||||||
|
dirpart=`AS_DIRNAME("$mf")`
|
||||||
|
else
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
grep '^DEP_FILES *= *[[^ @%:@]]' < "$mf" > /dev/null || continue
|
||||||
|
# Extract the definition of DEP_FILES from the Makefile without
|
||||||
|
# running `make'.
|
||||||
|
DEPDIR=`sed -n -e '/^DEPDIR = / s///p' < "$mf"`
|
||||||
|
test -z "$DEPDIR" && continue
|
||||||
|
# When using ansi2knr, U may be empty or an underscore; expand it
|
||||||
|
U=`sed -n -e '/^U = / s///p' < "$mf"`
|
||||||
|
test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR"
|
||||||
|
# We invoke sed twice because it is the simplest approach to
|
||||||
|
# changing $(DEPDIR) to its actual value in the expansion.
|
||||||
|
for file in `sed -n -e '
|
||||||
|
/^DEP_FILES = .*\\\\$/ {
|
||||||
|
s/^DEP_FILES = //
|
||||||
|
:loop
|
||||||
|
s/\\\\$//
|
||||||
|
p
|
||||||
|
n
|
||||||
|
/\\\\$/ b loop
|
||||||
|
p
|
||||||
|
}
|
||||||
|
/^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \
|
||||||
|
sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
|
||||||
|
# Make sure the directory exists.
|
||||||
|
test -f "$dirpart/$file" && continue
|
||||||
|
fdir=`AS_DIRNAME(["$file"])`
|
||||||
|
AS_MKDIR_P([$dirpart/$fdir])
|
||||||
|
# echo "creating $dirpart/$file"
|
||||||
|
echo '# dummy' > "$dirpart/$file"
|
||||||
|
done
|
||||||
|
done
|
||||||
|
])# _AM_OUTPUT_DEPENDENCY_COMMANDS
|
||||||
|
|
||||||
|
|
||||||
|
# AM_OUTPUT_DEPENDENCY_COMMANDS
|
||||||
|
# -----------------------------
|
||||||
|
# This macro should only be invoked once -- use via AC_REQUIRE.
|
||||||
|
#
|
||||||
|
# This code is only required when automatic dependency tracking
|
||||||
|
# is enabled. FIXME. This creates each `.P' file that we will
|
||||||
|
# need in order to bootstrap the dependency handling code.
|
||||||
|
AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
|
||||||
|
[AC_CONFIG_COMMANDS([depfiles],
|
||||||
|
[test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
|
||||||
|
[AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
|
||||||
|
])
|
||||||
|
|
||||||
|
# Copyright 2001 Free Software Foundation, Inc. -*- Autoconf -*-
|
||||||
|
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
# 02111-1307, USA.
|
||||||
|
|
||||||
|
# serial 2
|
||||||
|
|
||||||
|
# AM_MAKE_INCLUDE()
|
||||||
|
# -----------------
|
||||||
|
# Check to see how make treats includes.
|
||||||
|
AC_DEFUN([AM_MAKE_INCLUDE],
|
||||||
|
[am_make=${MAKE-make}
|
||||||
|
cat > confinc << 'END'
|
||||||
|
doit:
|
||||||
|
@echo done
|
||||||
|
END
|
||||||
|
# If we don't find an include directive, just comment out the code.
|
||||||
|
AC_MSG_CHECKING([for style of include used by $am_make])
|
||||||
|
am__include="#"
|
||||||
|
am__quote=
|
||||||
|
_am_result=none
|
||||||
|
# First try GNU make style include.
|
||||||
|
echo "include confinc" > confmf
|
||||||
|
# We grep out `Entering directory' and `Leaving directory'
|
||||||
|
# messages which can occur if `w' ends up in MAKEFLAGS.
|
||||||
|
# In particular we don't look at `^make:' because GNU make might
|
||||||
|
# be invoked under some other name (usually "gmake"), in which
|
||||||
|
# case it prints its new name instead of `make'.
|
||||||
|
if test "`$am_make -s -f confmf 2> /dev/null | fgrep -v 'ing directory'`" = "done"; then
|
||||||
|
am__include=include
|
||||||
|
am__quote=
|
||||||
|
_am_result=GNU
|
||||||
|
fi
|
||||||
|
# Now try BSD make style include.
|
||||||
|
if test "$am__include" = "#"; then
|
||||||
|
echo '.include "confinc"' > confmf
|
||||||
|
if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
|
||||||
|
am__include=.include
|
||||||
|
am__quote="\""
|
||||||
|
_am_result=BSD
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
AC_SUBST(am__include)
|
||||||
|
AC_SUBST(am__quote)
|
||||||
|
AC_MSG_RESULT($_am_result)
|
||||||
|
rm -f confinc confmf
|
||||||
|
])
|
||||||
|
|
||||||
|
# AM_CONDITIONAL -*- Autoconf -*-
|
||||||
|
|
||||||
|
# Copyright 1997, 2000, 2001 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
# 02111-1307, USA.
|
||||||
|
|
||||||
|
# serial 5
|
||||||
|
|
||||||
|
AC_PREREQ(2.52)
|
||||||
|
|
||||||
|
# AM_CONDITIONAL(NAME, SHELL-CONDITION)
|
||||||
|
# -------------------------------------
|
||||||
|
# Define a conditional.
|
||||||
|
AC_DEFUN([AM_CONDITIONAL],
|
||||||
|
[ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
|
||||||
|
[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
|
||||||
|
AC_SUBST([$1_TRUE])
|
||||||
|
AC_SUBST([$1_FALSE])
|
||||||
|
if $2; then
|
||||||
|
$1_TRUE=
|
||||||
|
$1_FALSE='#'
|
||||||
|
else
|
||||||
|
$1_TRUE='#'
|
||||||
|
$1_FALSE=
|
||||||
|
fi
|
||||||
|
AC_CONFIG_COMMANDS_PRE(
|
||||||
|
[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
|
||||||
|
AC_MSG_ERROR([conditional \"$1\" was never defined.
|
||||||
|
Usually this means the macro was only invoked conditionally.])
|
||||||
|
fi])])
|
||||||
|
|
||||||
|
# Like AC_CONFIG_HEADER, but automatically create stamp file. -*- Autoconf -*-
|
||||||
|
|
||||||
|
# Copyright 1996, 1997, 2000, 2001 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
# 02111-1307, USA.
|
||||||
|
|
||||||
|
AC_PREREQ([2.52])
|
||||||
|
|
||||||
|
# serial 6
|
||||||
|
|
||||||
|
# When config.status generates a header, we must update the stamp-h file.
|
||||||
|
# This file resides in the same directory as the config header
|
||||||
|
# that is generated. We must strip everything past the first ":",
|
||||||
|
# and everything past the last "/".
|
||||||
|
|
||||||
|
# _AM_DIRNAME(PATH)
|
||||||
|
# -----------------
|
||||||
|
# Like AS_DIRNAME, only do it during macro expansion
|
||||||
|
AC_DEFUN([_AM_DIRNAME],
|
||||||
|
[m4_if(regexp([$1], [^.*[^/]//*[^/][^/]*/*$]), -1,
|
||||||
|
m4_if(regexp([$1], [^//\([^/]\|$\)]), -1,
|
||||||
|
m4_if(regexp([$1], [^/.*]), -1,
|
||||||
|
[.],
|
||||||
|
patsubst([$1], [^\(/\).*], [\1])),
|
||||||
|
patsubst([$1], [^\(//\)\([^/].*\|$\)], [\1])),
|
||||||
|
patsubst([$1], [^\(.*[^/]\)//*[^/][^/]*/*$], [\1]))[]dnl
|
||||||
|
])# _AM_DIRNAME
|
||||||
|
|
||||||
|
|
||||||
|
# The stamp files are numbered to have different names.
|
||||||
|
# We could number them on a directory basis, but that's additional
|
||||||
|
# complications, let's have a unique counter.
|
||||||
|
m4_define([_AM_STAMP_Count], [0])
|
||||||
|
|
||||||
|
|
||||||
|
# _AM_STAMP(HEADER)
|
||||||
|
# -----------------
|
||||||
|
# The name of the stamp file for HEADER.
|
||||||
|
AC_DEFUN([_AM_STAMP],
|
||||||
|
[m4_define([_AM_STAMP_Count], m4_incr(_AM_STAMP_Count))dnl
|
||||||
|
AS_ESCAPE(_AM_DIRNAME(patsubst([$1],
|
||||||
|
[:.*])))/stamp-h[]_AM_STAMP_Count])
|
||||||
|
|
||||||
|
|
||||||
|
# _AM_CONFIG_HEADER(HEADER[:SOURCES], COMMANDS, INIT-COMMANDS)
|
||||||
|
# ------------------------------------------------------------
|
||||||
|
# We used to try to get a real timestamp in stamp-h. But the fear is that
|
||||||
|
# that will cause unnecessary cvs conflicts.
|
||||||
|
AC_DEFUN([_AM_CONFIG_HEADER],
|
||||||
|
[# Add the stamp file to the list of files AC keeps track of,
|
||||||
|
# along with our hook.
|
||||||
|
AC_CONFIG_HEADERS([$1],
|
||||||
|
[# update the timestamp
|
||||||
|
echo 'timestamp for $1' >"_AM_STAMP([$1])"
|
||||||
|
$2],
|
||||||
|
[$3])
|
||||||
|
])# _AM_CONFIG_HEADER
|
||||||
|
|
||||||
|
|
||||||
|
# AM_CONFIG_HEADER(HEADER[:SOURCES]..., COMMANDS, INIT-COMMANDS)
|
||||||
|
# --------------------------------------------------------------
|
||||||
|
AC_DEFUN([AM_CONFIG_HEADER],
|
||||||
|
[AC_FOREACH([_AM_File], [$1], [_AM_CONFIG_HEADER(_AM_File, [$2], [$3])])
|
||||||
|
])# AM_CONFIG_HEADER
|
||||||
|
|
16
autogen.sh
16
autogen.sh
@ -1,14 +1,18 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
#
|
||||||
echo "Generating build information using aclocal, autoheader, automake and autoconf"
|
echo "Generating build information using aclocal, auotheader, automake and autoconf"
|
||||||
echo "This may take a while ..."
|
echo "This may take a while ..."
|
||||||
|
|
||||||
# Regenerate configuration files.
|
# Touch the timestamps on all the files since CVS messes them up
|
||||||
|
directory=`dirname $0`
|
||||||
|
touch $directory/configure.in
|
||||||
|
|
||||||
|
# Regenerate configuration files
|
||||||
|
|
||||||
aclocal
|
aclocal
|
||||||
autoheader
|
autoheader
|
||||||
automake --include-deps --add-missing --copy
|
automake --gnits --include-deps --add-missing --copy
|
||||||
autoconf
|
autoconf
|
||||||
|
|
||||||
echo "Now you are ready to run ./configure."
|
cp $directory/settings.h.cvs $directory/settings.h
|
||||||
echo "You can also run ./configure --help for extra features to enable/disable."
|
echo "Now you are ready to run ./configure also check settings.h for extra build settings"
|
||||||
|
1368
config.guess
vendored
Normal file
1368
config.guess
vendored
Normal file
File diff suppressed because it is too large
Load Diff
65
config.h.in
Normal file
65
config.h.in
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/* config.h.in. Generated from configure.in by autoheader. */
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||||
|
#undef HAVE_INTTYPES_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <memory.h> header file. */
|
||||||
|
#undef HAVE_MEMORY_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <stdint.h> header file. */
|
||||||
|
#undef HAVE_STDINT_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||||
|
#undef HAVE_STDLIB_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <strings.h> header file. */
|
||||||
|
#undef HAVE_STRINGS_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <string.h> header file. */
|
||||||
|
#undef HAVE_STRING_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||||
|
#undef HAVE_SYS_STAT_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||||
|
#undef HAVE_SYS_TYPES_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <unistd.h> header file. */
|
||||||
|
#undef HAVE_UNISTD_H
|
||||||
|
|
||||||
|
/* Name of package */
|
||||||
|
#undef PACKAGE
|
||||||
|
|
||||||
|
/* Define to the address where bug reports for this package should be sent. */
|
||||||
|
#undef PACKAGE_BUGREPORT
|
||||||
|
|
||||||
|
/* Define to the full name of this package. */
|
||||||
|
#undef PACKAGE_NAME
|
||||||
|
|
||||||
|
/* Define to the full name and version of this package. */
|
||||||
|
#undef PACKAGE_STRING
|
||||||
|
|
||||||
|
/* Define to the one symbol short name of this package. */
|
||||||
|
#undef PACKAGE_TARNAME
|
||||||
|
|
||||||
|
/* Define to the version of this package. */
|
||||||
|
#undef PACKAGE_VERSION
|
||||||
|
|
||||||
|
/* Define to 1 if you have the ANSI C header files. */
|
||||||
|
#undef STDC_HEADERS
|
||||||
|
|
||||||
|
/* Define to 1 if your <sys/time.h> declares `struct tm'. */
|
||||||
|
#undef TM_IN_SYS_TIME
|
||||||
|
|
||||||
|
/* Version number of package */
|
||||||
|
#undef VERSION
|
||||||
|
|
||||||
|
/* Define to empty if `const' does not conform to ANSI C. */
|
||||||
|
#undef const
|
||||||
|
|
||||||
|
/* Define as `__inline' if that's what the C compiler calls it, or to nothing
|
||||||
|
if it is not supported. */
|
||||||
|
#undef inline
|
||||||
|
|
||||||
|
/* Define to `unsigned' if <sys/types.h> does not define. */
|
||||||
|
#undef size_t
|
1443
config.sub
vendored
Normal file
1443
config.sub
vendored
Normal file
File diff suppressed because it is too large
Load Diff
474
configure.in
474
configure.in
@ -1,6 +1,5 @@
|
|||||||
dnl Init.
|
dnl Init.
|
||||||
AC_INIT(dosbox,0.72)
|
AC_INIT(dosbox,0.50)
|
||||||
AC_PREREQ(2.50)
|
|
||||||
AC_CONFIG_SRCDIR(README)
|
AC_CONFIG_SRCDIR(README)
|
||||||
|
|
||||||
dnl Detect the canonical host and target build environment
|
dnl Detect the canonical host and target build environment
|
||||||
@ -11,6 +10,7 @@ dnl Setup for automake
|
|||||||
AM_INIT_AUTOMAKE
|
AM_INIT_AUTOMAKE
|
||||||
AM_CONFIG_HEADER(config.h)
|
AM_CONFIG_HEADER(config.h)
|
||||||
|
|
||||||
|
|
||||||
dnl Checks for programs.
|
dnl Checks for programs.
|
||||||
AC_PROG_MAKE_SET
|
AC_PROG_MAKE_SET
|
||||||
AC_PROG_CC
|
AC_PROG_CC
|
||||||
@ -19,14 +19,6 @@ AC_PROG_CXX
|
|||||||
AC_PROG_INSTALL
|
AC_PROG_INSTALL
|
||||||
AC_PROG_RANLIB
|
AC_PROG_RANLIB
|
||||||
|
|
||||||
dnl Some needed libaries for OS2
|
|
||||||
dnl perharps join this with the other target depended checks. move them upwards
|
|
||||||
if test x$target = xi386-pc-os2-emx ; then
|
|
||||||
CXXFLAGS="$CXXFLAGS -Zmt"
|
|
||||||
LDFLAGS="$LDFLAGS -Zomf -Zmt"
|
|
||||||
LIBS="$LIBS -los2me"
|
|
||||||
fi
|
|
||||||
|
|
||||||
dnl Check for SDL
|
dnl Check for SDL
|
||||||
SDL_VERSION=1.2.0
|
SDL_VERSION=1.2.0
|
||||||
AM_PATH_SDL($SDL_VERSION,
|
AM_PATH_SDL($SDL_VERSION,
|
||||||
@ -34,21 +26,7 @@ AM_PATH_SDL($SDL_VERSION,
|
|||||||
AC_MSG_ERROR([*** SDL version $SDL_VERSION not found!])
|
AC_MSG_ERROR([*** SDL version $SDL_VERSION not found!])
|
||||||
)
|
)
|
||||||
LIBS="$LIBS $SDL_LIBS"
|
LIBS="$LIBS $SDL_LIBS"
|
||||||
CPPFLAGS="$CPPFLAGS $SDL_CFLAGS"
|
CXXFLAGS="$CXXFLAGS $SDL_CFLAGS"
|
||||||
|
|
||||||
dnl Check if SDL is 1.2.x (1.3 not supported)
|
|
||||||
AC_MSG_CHECKING([SDL version only being 1.2.X])
|
|
||||||
AC_COMPILE_IFELSE([
|
|
||||||
#include "SDL.h"
|
|
||||||
void blah(){
|
|
||||||
#if SDL_MINOR_VERSION != 2
|
|
||||||
#error "Only SDL 1.2 supported"
|
|
||||||
#endif
|
|
||||||
;
|
|
||||||
}
|
|
||||||
],AC_MSG_RESULT([yes]),[
|
|
||||||
AC_MSG_RESULT([no])
|
|
||||||
AC_MSG_ERROR([Only libSDL 1.2.X supported])])
|
|
||||||
|
|
||||||
dnl Checks for header files.
|
dnl Checks for header files.
|
||||||
|
|
||||||
@ -57,463 +35,27 @@ AC_C_CONST
|
|||||||
AC_C_INLINE
|
AC_C_INLINE
|
||||||
AC_TYPE_SIZE_T
|
AC_TYPE_SIZE_T
|
||||||
AC_STRUCT_TM
|
AC_STRUCT_TM
|
||||||
AC_CHECK_SIZEOF(unsigned char)
|
|
||||||
AC_CHECK_SIZEOF(unsigned short)
|
|
||||||
AC_CHECK_SIZEOF(unsigned int)
|
|
||||||
AC_CHECK_SIZEOF(unsigned long)
|
|
||||||
AC_CHECK_SIZEOF(unsigned long long)
|
|
||||||
AC_CHECK_SIZEOF(int *)
|
|
||||||
|
|
||||||
dnl some semi complex check for sys/socket so it works on darwin as well
|
dnl Checks for library functions.
|
||||||
AC_CHECK_HEADERS([stdlib.h sys/types.h])
|
|
||||||
AC_CHECK_HEADERS([sys/socket.h netinet/in.h pwd.h], [], [],
|
|
||||||
[#include <stdio.h>
|
|
||||||
#ifdef STDC_HEADERS
|
|
||||||
# include <stdlib.h>
|
|
||||||
# include <stddef.h>
|
|
||||||
#else
|
|
||||||
# ifdef HAVE_STDLIB_H
|
|
||||||
# include <stdlib.h>
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
|
||||||
# include <sys/types.h>
|
|
||||||
#endif
|
|
||||||
])
|
|
||||||
|
|
||||||
dnl check for the socklen_t (darwin doesn't always have it)
|
|
||||||
AC_COMPILE_IFELSE([
|
|
||||||
#include <stdio.h>
|
|
||||||
#ifdef STDC_HEADERS
|
|
||||||
# include <stdlib.h>
|
|
||||||
# include <stddef.h>
|
|
||||||
#else
|
|
||||||
# ifdef HAVE_STDLIB_H
|
|
||||||
# include <stdlib.h>
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
|
||||||
# include <sys/types.h>
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_SYS_SOCKET_H
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#endif
|
|
||||||
],[],[AC_DEFINE([socklen_t],[int],[Define to `int` if you don't have socklen_t])])
|
|
||||||
|
|
||||||
AC_MSG_CHECKING(if environ can be included)
|
|
||||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdlib.h>]],[[*environ;]])],
|
|
||||||
[AC_MSG_RESULT(yes);AC_DEFINE(ENVIRON_INCLUDED,1,[environ can be included])],AC_MSG_RESULT(no))
|
|
||||||
|
|
||||||
AC_MSG_CHECKING(if environ can be linked)
|
|
||||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[extern char ** environ;]],[[*environ;]])],
|
|
||||||
[AC_MSG_RESULT(yes);AC_DEFINE(ENVIRON_LINKED,1,[environ can be linked])],AC_MSG_RESULT(no))
|
|
||||||
|
|
||||||
AC_MSG_CHECKING([if dirent includes d_type])
|
|
||||||
AC_COMPILE_IFELSE([
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <dirent.h>
|
|
||||||
void blah(){
|
|
||||||
struct dirent d_test;
|
|
||||||
d_test.d_type = 0;
|
|
||||||
}],[AC_MSG_RESULT(yes);AC_DEFINE(DIRENT_HAS_D_TYPE,1,[struct dirent has d_type])],AC_MSG_RESULT(no))
|
|
||||||
|
|
||||||
|
|
||||||
dnl Check for powf
|
#Always include the standard include dir in all makefiless
|
||||||
if test x$target = xi386-pc-os2-emx ; then
|
|
||||||
AC_MSG_CHECKING(for powf in libm);
|
|
||||||
LIBS_BACKUP=$LIBS;
|
|
||||||
LIBS="$LIBS -lm";
|
|
||||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <math.h>]],[[
|
|
||||||
powf(1.0f, 1.0f);
|
|
||||||
]])], [AC_MSG_RESULT(yes)], [AC_DEFINE([DB_HAVE_NO_POWF],[1],[libm doesn't include powf])])
|
|
||||||
LIBS=$LIBS_BACKUP
|
|
||||||
else
|
|
||||||
AC_CHECK_LIB([m],[powf],,[AC_DEFINE([DB_HAVE_NO_POWF],[1],[libm doesn't include powf])])
|
|
||||||
fi
|
|
||||||
|
|
||||||
dnl Checks for libraries.
|
AC_OUTPUT([
|
||||||
|
|
||||||
#Check if the compiler support attributes
|
|
||||||
AH_TEMPLATE([C_HAS_ATTRIBUTE],[Determines if the compilers supports attributes for structures.])
|
|
||||||
AC_MSG_CHECKING(if compiler allows __attribute__)
|
|
||||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
|
||||||
typedef struct { } __attribute__((packed)) junk;]],
|
|
||||||
[[ ]])],[ AC_MSG_RESULT(yes);AC_DEFINE(C_HAS_ATTRIBUTE)],AC_MSG_RESULT(no))
|
|
||||||
|
|
||||||
|
|
||||||
#Check if the compiler supports certain attributes
|
|
||||||
OLDCFLAGS="$CFLAGS"
|
|
||||||
CFLAGS="-Werror"
|
|
||||||
|
|
||||||
AH_TEMPLATE([C_ATTRIBUTE_ALWAYS_INLINE],[Determines if the compilers supports always_inline attribute.])
|
|
||||||
AC_MSG_CHECKING(if compiler allows __attribute__((always_inline)) )
|
|
||||||
AC_COMPILE_IFELSE([ void __attribute__((always_inline)) test(){}
|
|
||||||
],[ AC_MSG_RESULT(yes);AC_DEFINE(C_ATTRIBUTE_ALWAYS_INLINE)],AC_MSG_RESULT(no))
|
|
||||||
|
|
||||||
AH_TEMPLATE([C_ATTRIBUTE_FASTCALL],[Determines if the compilers supports fastcall attribute.])
|
|
||||||
AC_MSG_CHECKING(if compiler allows __attribute__((fastcall)) )
|
|
||||||
AC_COMPILE_IFELSE([ void __attribute__((fastcall)) test(){}
|
|
||||||
],[ AC_MSG_RESULT(yes);AC_DEFINE(C_ATTRIBUTE_FASTCALL)],AC_MSG_RESULT(no))
|
|
||||||
|
|
||||||
|
|
||||||
CFLAGS="$OLDCFLAGS"
|
|
||||||
|
|
||||||
|
|
||||||
#Check if the compiler supports __builtin_expect
|
|
||||||
#Switch language to c++
|
|
||||||
AC_LANG_PUSH(C++)
|
|
||||||
AH_TEMPLATE([C_HAS_BUILTIN_EXPECT],[Determines if the compilers supports __builtin_expect for branch prediction.])
|
|
||||||
AC_MSG_CHECKING(if compiler allows __builtin_expect)
|
|
||||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]],[[
|
|
||||||
int x=10;if( __builtin_expect ((x==1),0) ) ;
|
|
||||||
]])], [ AC_MSG_RESULT(yes);AC_DEFINE(C_HAS_BUILTIN_EXPECT)],AC_MSG_RESULT(no))
|
|
||||||
#switch language back
|
|
||||||
AC_LANG_POP(C++)
|
|
||||||
|
|
||||||
dnl enable disable alsa and pass it's cflags to CXXFLAGS
|
|
||||||
AC_ARG_ENABLE(alsa-midi,
|
|
||||||
AC_HELP_STRING([--enable-alsa-midi],[compile with alsa midi support (default yes)]),
|
|
||||||
[ case "${enableval}" in
|
|
||||||
yes) alsa_midi=true;;
|
|
||||||
no) alsa_midi=false;;
|
|
||||||
esac],
|
|
||||||
[alsa_midi=true])
|
|
||||||
if test x$alsa_midi = xtrue ; then
|
|
||||||
AM_PATH_ALSA(0.9.0, AC_DEFINE(HAVE_ALSA,1,[Define to 1 to use ALSA for MIDI]) , : )
|
|
||||||
CXXFLAGS="$CXXFLAGS $ALSA_CFLAGS"
|
|
||||||
fi
|
|
||||||
|
|
||||||
#Check for big endian machine, should #define WORDS_BIGENDIAN if so
|
|
||||||
AC_C_BIGENDIAN
|
|
||||||
|
|
||||||
#Features to enable/disable
|
|
||||||
AH_TEMPLATE(C_DEBUG,[Define to 1 to enable internal debugger, requires libcurses])
|
|
||||||
AH_TEMPLATE(C_HEAVY_DEBUG,[Define to 1 to enable heavy debugging, also have to enable C_DEBUG])
|
|
||||||
AC_ARG_ENABLE(debug,AC_HELP_STRING([--enable-debug],[Enable debug mode]),[
|
|
||||||
AC_CHECK_HEADER(curses.h,have_curses_h=yes,)
|
|
||||||
AC_CHECK_LIB(curses, initscr, have_curses_lib=yes, , )
|
|
||||||
AC_CHECK_LIB(ncurses, initscr, have_ncurses_lib=yes, , )
|
|
||||||
AC_CHECK_LIB(pdcurses, initscr, have_pdcurses_lib=yes, , )
|
|
||||||
|
|
||||||
if test x$enable_debug = xno; then
|
|
||||||
AC_MSG_RESULT([Debugger not enabled])
|
|
||||||
elif test x$have_curses_lib = xyes -a x$have_curses_h = xyes ; then
|
|
||||||
LIBS="$LIBS -lcurses"
|
|
||||||
AC_DEFINE(C_DEBUG,1)
|
|
||||||
if test x$enable_debug = xheavy ; then
|
|
||||||
AC_DEFINE(C_HEAVY_DEBUG,1)
|
|
||||||
fi
|
|
||||||
elif test x$have_ncurses_lib = xyes -a x$have_curses_h = xyes ; then
|
|
||||||
LIBS="$LIBS -lncurses"
|
|
||||||
AC_DEFINE(C_DEBUG,1)
|
|
||||||
if test x$enable_debug = xheavy ; then
|
|
||||||
AC_DEFINE(C_HEAVY_DEBUG,1)
|
|
||||||
fi
|
|
||||||
elif test x$have_pdcurses_lib = xyes -a x$have_curses_h = xyes ; then
|
|
||||||
LIBS="$LIBS -lpdcurses"
|
|
||||||
AC_DEFINE(C_DEBUG,1)
|
|
||||||
if test x$enable_debug = xheavy ; then
|
|
||||||
AC_DEFINE(C_HEAVY_DEBUG,1)
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
AC_MSG_ERROR([Can't find curses, which is required for debug mode])
|
|
||||||
fi
|
|
||||||
],)
|
|
||||||
|
|
||||||
AH_TEMPLATE(C_CORE_INLINE,[Define to 1 to use inlined memory functions in cpu core])
|
|
||||||
AC_ARG_ENABLE(core-inline,AC_HELP_STRING([--enable-core-inline],[Enable inlined memory handling in CPU Core]),[
|
|
||||||
if test x$enable_core_inline = xyes ; then
|
|
||||||
AC_MSG_RESULT([enabling inlined memory handling in CPU Core])
|
|
||||||
AC_DEFINE(C_CORE_INLINE,1)
|
|
||||||
fi
|
|
||||||
],)
|
|
||||||
|
|
||||||
|
|
||||||
dnl The target cpu checks for dynamic cores
|
|
||||||
AH_TEMPLATE(C_TARGETCPU,[The type of cpu this target has])
|
|
||||||
AC_MSG_CHECKING(for target cpu type)
|
|
||||||
case "$target_cpu" in
|
|
||||||
x86_64 | amd64)
|
|
||||||
AC_DEFINE(C_TARGETCPU,X86_64)
|
|
||||||
AC_MSG_RESULT(x86-64 bit compatible)
|
|
||||||
c_targetcpu="x86_64"
|
|
||||||
c_unalignedmemory=yes
|
|
||||||
;;
|
|
||||||
i?86)
|
|
||||||
AC_DEFINE(C_TARGETCPU,X86)
|
|
||||||
AC_MSG_RESULT(x86 compatible)
|
|
||||||
c_targetcpu="x86"
|
|
||||||
c_unalignedmemory=yes
|
|
||||||
;;
|
|
||||||
powerpc*)
|
|
||||||
AC_DEFINE(C_TARGETCPU,POWERPC)
|
|
||||||
AC_MSG_RESULT(Power PC)
|
|
||||||
c_targetcpu="powerpc"
|
|
||||||
c_unalignedmemory=yes
|
|
||||||
;;
|
|
||||||
m68k*)
|
|
||||||
AC_DEFINE(C_TARGETCPU,M68K)
|
|
||||||
AC_MSG_RESULT(Motorola 68000)
|
|
||||||
c_targetcpu="m68k"
|
|
||||||
c_unalignedmemory=yes
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
AC_DEFINE(C_TARGETCPU,UNKNOWN)
|
|
||||||
AC_MSG_RESULT(unknown)
|
|
||||||
c_unalignedmemory=no
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
AC_ARG_ENABLE(dynamic-core,AC_HELP_STRING([--disable-dynamic-core],[Disable all dynamic cores]),,enable_dynamic_core=yes)
|
|
||||||
|
|
||||||
AH_TEMPLATE(C_DYNAMIC_X86,[Define to 1 to use x86 dynamic cpu core])
|
|
||||||
AC_ARG_ENABLE(dynamic-x86,AC_HELP_STRING([--disable-dynamic-x86],[Disable x86 dynamic cpu core]),,enable_dynamic_x86=yes)
|
|
||||||
AC_MSG_CHECKING(whether x86 dynamic cpu core will be enabled)
|
|
||||||
if test x$enable_dynamic_x86 = xno -o x$enable_dynamic_core = xno; then
|
|
||||||
AC_MSG_RESULT(no)
|
|
||||||
else
|
|
||||||
if test x$c_targetcpu = xx86 ; then
|
|
||||||
AC_DEFINE(C_DYNAMIC_X86,1)
|
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
else
|
|
||||||
AC_MSG_RESULT(no)
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
AH_TEMPLATE(C_DYNREC,[Define to 1 to use recompiling cpu core. Can not be used together with the dynamic-x86 core])
|
|
||||||
AC_ARG_ENABLE(dynrec,AC_HELP_STRING([--disable-dynrec],[Disable recompiling cpu core]),,enable_dynrec=yes)
|
|
||||||
AC_MSG_CHECKING(whether recompiling cpu core will be enabled)
|
|
||||||
if test x$enable_dynrec = xno -o x$enable_dynamic_core = xno; then
|
|
||||||
AC_MSG_RESULT(no)
|
|
||||||
else
|
|
||||||
dnl x86 only enable it if dynamic-x86 is disabled.
|
|
||||||
if test x$c_targetcpu = xx86 ; then
|
|
||||||
if test x$enable_dynamic_x86 = xno ; then
|
|
||||||
AC_DEFINE(C_DYNREC,1)
|
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
else
|
|
||||||
AC_MSG_RESULT([no, using dynamic-x86])
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
if test x$c_targetcpu = xx86_64 ; then
|
|
||||||
AC_DEFINE(C_DYNREC,1)
|
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
else
|
|
||||||
AC_MSG_RESULT(no)
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
AH_TEMPLATE(C_FPU,[Define to 1 to enable floating point emulation])
|
|
||||||
AC_ARG_ENABLE(fpu,AC_HELP_STRING([--disable-fpu],[Disable fpu support]),,enable_fpu=yes)
|
|
||||||
AC_MSG_CHECKING(whether fpu emulation will be enabled)
|
|
||||||
if test x$enable_fpu = xyes ; then
|
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
AC_DEFINE(C_FPU,1)
|
|
||||||
else
|
|
||||||
AC_MSG_RESULT(no)
|
|
||||||
fi
|
|
||||||
|
|
||||||
AH_TEMPLATE(C_FPU_X86,[Define to 1 to use a x86 assembly fpu core])
|
|
||||||
AC_ARG_ENABLE(fpu-x86,AC_HELP_STRING([--disable-fpu-x86],[Disable x86 assembly fpu core]),,enable_fpu_x86=yes)
|
|
||||||
AC_MSG_CHECKING(whether x86 assembly fpu core will be enabled)
|
|
||||||
if test x$enable_fpu_x86 = xno ; then
|
|
||||||
AC_MSG_RESULT(no)
|
|
||||||
else
|
|
||||||
if test x$enable_fpu = xyes; then
|
|
||||||
if test x$c_targetcpu = xx86 ; then
|
|
||||||
AC_DEFINE(C_FPU_X86,1)
|
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
else
|
|
||||||
AC_MSG_RESULT(no)
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
AC_MSG_RESULT(no)
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
AH_TEMPLATE(C_UNALIGNED_MEMORY,[Define to 1 to use a unaligned memory access])
|
|
||||||
AC_ARG_ENABLE(unaligned_memory,AC_HELP_STRING([--disable-unaligned-memory],[Disable unaligned memory access]),,enable_unaligned_memory=yes)
|
|
||||||
AC_MSG_CHECKING(whether to enable unaligned memory access)
|
|
||||||
if test x$enable_unaligned_memory = xyes -a x$c_unalignedmemory = xyes; then
|
|
||||||
AC_DEFINE(C_UNALIGNED_MEMORY,1)
|
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
else
|
|
||||||
AC_MSG_RESULT(no)
|
|
||||||
fi
|
|
||||||
|
|
||||||
AH_TEMPLATE(C_SSHOT,[Define to 1 to enable screenshots, requires libpng])
|
|
||||||
AC_CHECK_HEADER(png.h,have_png_h=yes,)
|
|
||||||
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 find libpng, screenshot support disabled])
|
|
||||||
fi
|
|
||||||
|
|
||||||
AH_TEMPLATE(C_MODEM,[Define to 1 to enable internal modem support, requires SDL_net])
|
|
||||||
AH_TEMPLATE(C_IPX,[Define to 1 to enable IPX over Internet networking, requires SDL_net])
|
|
||||||
AC_CHECK_HEADER(SDL_net.h,have_sdl_net_h=yes,)
|
|
||||||
|
|
||||||
if test x$target = xi386-pc-os2-emx ; then
|
|
||||||
AC_MSG_CHECKING(for SDLNet_Init in SDL_net);
|
|
||||||
LIBS_BACKUP=$LIBS;
|
|
||||||
LIBS="$LIBS -lSDL_Net";
|
|
||||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <SDL_Net.h>]],[[
|
|
||||||
SDLNet_Init ();
|
|
||||||
]])], [AC_MSG_RESULT(yes); have_sdl_net_lib=yes], AC_MSG_RESULT(no))
|
|
||||||
LIBS=$LIBS_BACKUP
|
|
||||||
else
|
|
||||||
AC_CHECK_LIB(SDL_net, SDLNet_Init, have_sdl_net_lib=yes, , )
|
|
||||||
fi
|
|
||||||
if test x$have_sdl_net_lib = xyes -a x$have_sdl_net_h = xyes ; then
|
|
||||||
LIBS="$LIBS -lSDL_net"
|
|
||||||
AC_DEFINE(C_MODEM,1)
|
|
||||||
AC_DEFINE(C_IPX,1)
|
|
||||||
else
|
|
||||||
AC_MSG_WARN([Can't find SDL_net, internal modem and ipx disabled])
|
|
||||||
fi
|
|
||||||
|
|
||||||
AH_TEMPLATE(C_OPENGL,[Define to 1 to use opengl display output support])
|
|
||||||
AC_CHECK_LIB(GL, main, have_gl_lib=yes, have_gl_lib=no , )
|
|
||||||
AC_CHECK_LIB(opengl32, main, have_opengl32_lib=yes,have_opengl32_lib=no , )
|
|
||||||
AC_CHECK_HEADER(GL/gl.h, have_gl_h=yes , have_gl_h=no , )
|
|
||||||
AC_ARG_ENABLE(opengl,AC_HELP_STRING([--disable-opengl],[Disable opengl support]),,enable_opengl=yes)
|
|
||||||
AC_MSG_CHECKING(whether opengl display output will be enabled)
|
|
||||||
if test x$enable_opengl = xyes; then
|
|
||||||
case "$target" in
|
|
||||||
*-*-darwin*)
|
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
LIBS="$LIBS -framework OpenGL"
|
|
||||||
AC_DEFINE(C_OPENGL,1)
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
if test x$have_gl_h = xyes -a x$have_gl_lib = xyes ; then
|
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
LIBS="$LIBS -lGL"
|
|
||||||
AC_DEFINE(C_OPENGL,1)
|
|
||||||
elif test x$have_gl_h = xyes -a x$have_opengl32_lib = xyes ; then
|
|
||||||
AC_MSG_RESULT(yes)
|
|
||||||
LIBS="$LIBS -lopengl32"
|
|
||||||
AC_DEFINE(C_OPENGL,1)
|
|
||||||
else
|
|
||||||
AC_MSG_RESULT(no)
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
fi
|
|
||||||
|
|
||||||
AH_TEMPLATE(C_SDL_SOUND,[Define to 1 to enable SDL_sound support])
|
|
||||||
AC_CHECK_HEADER(SDL_sound.h,have_SDL_sound_h=yes,)
|
|
||||||
AC_CHECK_LIB(SDL_sound, Sound_Init, have_SDL_sound_init=yes,,)
|
|
||||||
AC_CHECK_LIB(SDL_sound, Sound_Seek, have_SDL_sound_seek=yes,,)
|
|
||||||
if test x$have_SDL_sound_h = xyes -a x$have_SDL_sound_init = xyes ; then
|
|
||||||
if test x$have_SDL_sound_seek = xyes ; then
|
|
||||||
LIBS="-lSDL_sound $LIBS"
|
|
||||||
AC_DEFINE(C_SDL_SOUND,1)
|
|
||||||
else
|
|
||||||
AC_MSG_WARN([Can't find SoundSeek in libSDL_Sound, libSDL_sound support disabled])
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
AC_MSG_WARN([Can't find libSDL_sound, libSDL_sound support disabled])
|
|
||||||
fi
|
|
||||||
|
|
||||||
dnl Check for mprotect. Needed for 64 bits linux
|
|
||||||
AH_TEMPLATE(C_HAVE_MPROTECT,[Define to 1 if you have the mprotect function])
|
|
||||||
AC_CHECK_HEADER([sys/mman.h], [
|
|
||||||
AC_CHECK_FUNC([mprotect],[AC_DEFINE(C_HAVE_MPROTECT,1)])
|
|
||||||
])
|
|
||||||
|
|
||||||
dnl Setpriority
|
|
||||||
AH_TEMPLATE(C_SET_PRIORITY,[Define to 1 if you have setpriority support])
|
|
||||||
AC_MSG_CHECKING(for setpriority support)
|
|
||||||
AC_LINK_IFELSE([
|
|
||||||
#include <sys/resource.h>
|
|
||||||
int main(int argc,char * argv[]) {
|
|
||||||
return setpriority (PRIO_PROCESS, 0,PRIO_MIN+PRIO_MAX);
|
|
||||||
};
|
|
||||||
],AC_MSG_RESULT(yes);AC_DEFINE(C_SET_PRIORITY,1),AC_MSG_RESULT(no))
|
|
||||||
|
|
||||||
|
|
||||||
dnl Some target detection and actions for them
|
|
||||||
case "$target" in
|
|
||||||
*-*-cygwin* | *-*-mingw32*)
|
|
||||||
LIBS="$LIBS -lwinmm"
|
|
||||||
AC_CHECK_HEADERS(ddraw.h)
|
|
||||||
AC_DEFINE(C_DIRECTSERIAL, 1, [ Define to 1 if you want serial passthrough support (Win32, Posix and OS/2 only).])
|
|
||||||
if test x$have_sdl_net_lib = xyes -a x$have_sdl_net_h = xyes ; then
|
|
||||||
LIBS="$LIBS -lws2_32"
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
*-*-darwin*)
|
|
||||||
dnl We have a problem here: both Mac OS 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 CoreMidi -framework AudioUnit -framework AudioToolbox"
|
|
||||||
AC_DEFINE(C_DIRECTSERIAL, 1, [ Define to 1 if you want serial passthrough support (Win32, Posix and OS/2).])
|
|
||||||
;;
|
|
||||||
*-*-linux*)
|
|
||||||
AC_DEFINE(LINUX, 1, [Compiling on GNU/Linux])
|
|
||||||
AC_DEFINE(C_DIRECTSERIAL, 1, [ Define to 1 if you want serial passthrough support (Win32, Posix and OS/2).])
|
|
||||||
;;
|
|
||||||
*-*-freebsd* | *-*-dragonfly* | *-*-netbsd* | *-*-openbsd*)
|
|
||||||
dnl Disabled directserial for now. It doesn't do anything without
|
|
||||||
dnl specifying an extra ifdef in directserial_posix.*
|
|
||||||
dnl directserial detection should be rewritten to test for the needed
|
|
||||||
dnl functions and headers. I currently do not know
|
|
||||||
dnl which ones are needed for BSD
|
|
||||||
AC_DEFINE(BSD, 1, [Compiling on BSD])
|
|
||||||
AC_DEFINE(C_DIRECTSERIAL, 1, [ Define to 1 if you want serial passthrough support (Win32, Posix and OS/2).])
|
|
||||||
;;
|
|
||||||
*-*-os2-emx*)
|
|
||||||
AC_DEFINE(OS2, 1, [Compiling on OS/2 EMX])
|
|
||||||
AC_DEFINE(C_DIRECTSERIAL, 1, [ Define to 1 if you want serial passthrough support (Win32, Posix and OS/2).])
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
dnl Some stuff for the icon.
|
|
||||||
case "$target" in
|
|
||||||
*-*-cygwin* | *-*-mingw32*)
|
|
||||||
dnl Some stuff for the ico
|
|
||||||
AC_CHECK_TOOL(WINDRES, windres, :)
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
WINDRES=":"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
AM_CONDITIONAL(HAVE_WINDRES, test "x$WINDRES" != "x:")
|
|
||||||
AC_SUBST(WINDRES)
|
|
||||||
|
|
||||||
|
|
||||||
AC_CONFIG_FILES([
|
|
||||||
Makefile
|
Makefile
|
||||||
src/Makefile
|
src/Makefile
|
||||||
src/cpu/Makefile
|
src/cpu/Makefile
|
||||||
src/cpu/core_full/Makefile
|
src/cpu/core_16/Makefile
|
||||||
src/cpu/core_normal/Makefile
|
|
||||||
src/cpu/core_dyn_x86/Makefile
|
|
||||||
src/cpu/core_dynrec/Makefile
|
|
||||||
src/debug/Makefile
|
src/debug/Makefile
|
||||||
src/dos/Makefile
|
src/dos/Makefile
|
||||||
src/fpu/Makefile
|
src/fpu/Makefile
|
||||||
src/gui/Makefile
|
src/gui/Makefile
|
||||||
src/hardware/Makefile
|
src/hardware/Makefile
|
||||||
src/hardware/serialport/Makefile
|
|
||||||
src/ints/Makefile
|
src/ints/Makefile
|
||||||
src/libs/Makefile
|
|
||||||
src/libs/zmbv/Makefile
|
|
||||||
src/libs/gui_tk/Makefile
|
|
||||||
src/misc/Makefile
|
src/misc/Makefile
|
||||||
src/shell/Makefile
|
src/shell/Makefile
|
||||||
src/platform/Makefile
|
src/platform/Makefile
|
||||||
src/platform/visualc/Makefile
|
src/platform/visualc/Makefile
|
||||||
visualc_net/Makefile
|
visualc/Makefile
|
||||||
include/Makefile
|
include/Makefile
|
||||||
docs/Makefile
|
|
||||||
])
|
])
|
||||||
AC_OUTPUT
|
|
||||||
|
436
depcomp
Normal file
436
depcomp
Normal file
@ -0,0 +1,436 @@
|
|||||||
|
#! /bin/sh
|
||||||
|
|
||||||
|
# depcomp - compile a program generating dependencies as side-effects
|
||||||
|
# Copyright 1999, 2000 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
# 02111-1307, USA.
|
||||||
|
|
||||||
|
# As a special exception to the GNU General Public License, if you
|
||||||
|
# distribute this file as part of a program that contains a
|
||||||
|
# configuration script generated by Autoconf, you may include it under
|
||||||
|
# the same distribution terms that you use for the rest of that program.
|
||||||
|
|
||||||
|
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
|
||||||
|
|
||||||
|
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
|
||||||
|
echo "depcomp: Variables source, object and depmode must be set" 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
# `libtool' can also be set to `yes' or `no'.
|
||||||
|
|
||||||
|
if test -z "$depfile"; then
|
||||||
|
base=`echo "$object" | sed -e 's,^.*/,,' -e 's,\.\([^.]*\)$,.P\1,'`
|
||||||
|
dir=`echo "$object" | sed 's,/.*$,/,'`
|
||||||
|
if test "$dir" = "$object"; then
|
||||||
|
dir=
|
||||||
|
fi
|
||||||
|
# FIXME: should be _deps on DOS.
|
||||||
|
depfile="$dir.deps/$base"
|
||||||
|
fi
|
||||||
|
|
||||||
|
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
|
||||||
|
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
|
||||||
|
# Some modes work just like other modes, but use different flags. We
|
||||||
|
# parameterize here, but still list the modes in the big case below,
|
||||||
|
# to make depend.m4 easier to write. Note that we *cannot* use a case
|
||||||
|
# here, because this file can only contain one case statement.
|
||||||
|
if test "$depmode" = hp; then
|
||||||
|
# HP compiler uses -M and no extra arg.
|
||||||
|
gccflag=-M
|
||||||
|
depmode=gcc
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test "$depmode" = dashXmstdout; then
|
||||||
|
# This is just like dashmstdout with a different argument.
|
||||||
|
dashmflag=-xM
|
||||||
|
depmode=dashmstdout
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$depmode" in
|
||||||
|
gcc3)
|
||||||
|
## gcc 3 implements dependency tracking that does exactly what
|
||||||
|
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
|
||||||
|
## it if -MD -MP comes after the -MF stuff. Hmm.
|
||||||
|
"$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
|
||||||
|
stat=$?
|
||||||
|
if test $stat -eq 0; then :
|
||||||
|
else
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
mv "$tmpdepfile" "$depfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
gcc)
|
||||||
|
## There are various ways to get dependency output from gcc. Here's
|
||||||
|
## why we pick this rather obscure method:
|
||||||
|
## - Don't want to use -MD because we'd like the dependencies to end
|
||||||
|
## up in a subdir. Having to rename by hand is ugly.
|
||||||
|
## (We might end up doing this anyway to support other compilers.)
|
||||||
|
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
|
||||||
|
## -MM, not -M (despite what the docs say).
|
||||||
|
## - Using -M directly means running the compiler twice (even worse
|
||||||
|
## than renaming).
|
||||||
|
if test -z "$gccflag"; then
|
||||||
|
gccflag=-MD,
|
||||||
|
fi
|
||||||
|
"$@" -Wp,"$gccflag$tmpdepfile"
|
||||||
|
stat=$?
|
||||||
|
if test $stat -eq 0; then :
|
||||||
|
else
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
rm -f "$depfile"
|
||||||
|
echo "$object : \\" > "$depfile"
|
||||||
|
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
|
||||||
|
## The second -e expression handles DOS-style file names with drive letters.
|
||||||
|
sed -e 's/^[^:]*: / /' \
|
||||||
|
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
|
||||||
|
## This next piece of magic avoids the `deleted header file' problem.
|
||||||
|
## The problem is that when a header file which appears in a .P file
|
||||||
|
## is deleted, the dependency causes make to die (because there is
|
||||||
|
## typically no way to rebuild the header). We avoid this by adding
|
||||||
|
## dummy dependencies for each header file. Too bad gcc doesn't do
|
||||||
|
## this for us directly.
|
||||||
|
tr ' ' '
|
||||||
|
' < "$tmpdepfile" |
|
||||||
|
## Some versions of gcc put a space before the `:'. On the theory
|
||||||
|
## that the space means something, we add a space to the output as
|
||||||
|
## well.
|
||||||
|
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||||
|
## correctly. Breaking it into two sed invocations is a workaround.
|
||||||
|
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
hp)
|
||||||
|
# This case exists only to let depend.m4 do its work. It works by
|
||||||
|
# looking at the text of this script. This case will never be run,
|
||||||
|
# since it is checked for above.
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
sgi)
|
||||||
|
if test "$libtool" = yes; then
|
||||||
|
"$@" "-Wp,-MDupdate,$tmpdepfile"
|
||||||
|
else
|
||||||
|
"$@" -MDupdate "$tmpdepfile"
|
||||||
|
fi
|
||||||
|
stat=$?
|
||||||
|
if test $stat -eq 0; then :
|
||||||
|
else
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
rm -f "$depfile"
|
||||||
|
|
||||||
|
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
|
||||||
|
echo "$object : \\" > "$depfile"
|
||||||
|
|
||||||
|
# Clip off the initial element (the dependent). Don't try to be
|
||||||
|
# clever and replace this with sed code, as IRIX sed won't handle
|
||||||
|
# lines with more than a fixed number of characters (4096 in
|
||||||
|
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
|
||||||
|
# the IRIX cc adds comments like `#:fec' to the end of the
|
||||||
|
# dependency line.
|
||||||
|
tr ' ' '
|
||||||
|
' < "$tmpdepfile" \
|
||||||
|
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
|
||||||
|
tr '
|
||||||
|
' ' ' >> $depfile
|
||||||
|
echo >> $depfile
|
||||||
|
|
||||||
|
# The second pass generates a dummy entry for each header file.
|
||||||
|
tr ' ' '
|
||||||
|
' < "$tmpdepfile" \
|
||||||
|
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
|
||||||
|
>> $depfile
|
||||||
|
else
|
||||||
|
# The sourcefile does not contain any dependencies, so just
|
||||||
|
# store a dummy comment line, to avoid errors with the Makefile
|
||||||
|
# "include basename.Plo" scheme.
|
||||||
|
echo "#dummy" > "$depfile"
|
||||||
|
fi
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
aix)
|
||||||
|
# The C for AIX Compiler uses -M and outputs the dependencies
|
||||||
|
# in a .u file. This file always lives in the current directory.
|
||||||
|
# Also, the AIX compiler puts `$object:' at the start of each line;
|
||||||
|
# $object doesn't have directory information.
|
||||||
|
stripped=`echo "$object" | sed -e 's,^.*/,,' -e 's/\(.*\)\..*$/\1/'`
|
||||||
|
tmpdepfile="$stripped.u"
|
||||||
|
outname="$stripped.o"
|
||||||
|
if test "$libtool" = yes; then
|
||||||
|
"$@" -Wc,-M
|
||||||
|
else
|
||||||
|
"$@" -M
|
||||||
|
fi
|
||||||
|
|
||||||
|
stat=$?
|
||||||
|
if test $stat -eq 0; then :
|
||||||
|
else
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -f "$tmpdepfile"; then
|
||||||
|
# Each line is of the form `foo.o: dependent.h'.
|
||||||
|
# Do two passes, one to just change these to
|
||||||
|
# `$object: dependent.h' and one to simply `dependent.h:'.
|
||||||
|
sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
|
||||||
|
sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
|
||||||
|
else
|
||||||
|
# The sourcefile does not contain any dependencies, so just
|
||||||
|
# store a dummy comment line, to avoid errors with the Makefile
|
||||||
|
# "include basename.Plo" scheme.
|
||||||
|
echo "#dummy" > "$depfile"
|
||||||
|
fi
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
tru64)
|
||||||
|
# The Tru64 compiler uses -MD to generate dependencies as a side
|
||||||
|
# effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
|
||||||
|
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
|
||||||
|
# dependencies in `foo.d' instead, so we check for that too.
|
||||||
|
# Subdirectories are respected.
|
||||||
|
|
||||||
|
base=`echo "$object" | sed -e 's/\.o$//' -e 's/\.lo$//'`
|
||||||
|
tmpdepfile1="$base.o.d"
|
||||||
|
tmpdepfile2="$base.d"
|
||||||
|
if test "$libtool" = yes; then
|
||||||
|
"$@" -Wc,-MD
|
||||||
|
else
|
||||||
|
"$@" -MD
|
||||||
|
fi
|
||||||
|
|
||||||
|
stat=$?
|
||||||
|
if test $stat -eq 0; then :
|
||||||
|
else
|
||||||
|
rm -f "$tmpdepfile1" "$tmpdepfile2"
|
||||||
|
exit $stat
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test -f "$tmpdepfile1"; then
|
||||||
|
tmpdepfile="$tmpdepfile1"
|
||||||
|
else
|
||||||
|
tmpdepfile="$tmpdepfile2"
|
||||||
|
fi
|
||||||
|
if test -f "$tmpdepfile"; then
|
||||||
|
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
|
||||||
|
# That's a space and a tab in the [].
|
||||||
|
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
|
||||||
|
else
|
||||||
|
echo "#dummy" > "$depfile"
|
||||||
|
fi
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
#nosideeffect)
|
||||||
|
# This comment above is used by automake to tell side-effect
|
||||||
|
# dependency tracking mechanisms from slower ones.
|
||||||
|
|
||||||
|
dashmstdout)
|
||||||
|
# Important note: in order to support this mode, a compiler *must*
|
||||||
|
# always write the 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
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
"$@" $dashmflag | sed 's:^[^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
|
||||||
|
) &
|
||||||
|
proc=$!
|
||||||
|
"$@"
|
||||||
|
stat=$?
|
||||||
|
wait "$proc"
|
||||||
|
if test "$stat" != 0; then exit $stat; fi
|
||||||
|
rm -f "$depfile"
|
||||||
|
cat < "$tmpdepfile" > "$depfile"
|
||||||
|
tr ' ' '
|
||||||
|
' < "$tmpdepfile" | \
|
||||||
|
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||||
|
## correctly. Breaking it into two sed invocations is a workaround.
|
||||||
|
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
dashXmstdout)
|
||||||
|
# This case only exists to satisfy depend.m4. It is never actually
|
||||||
|
# run, as this mode is specially recognized in the preamble.
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
makedepend)
|
||||||
|
# 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
|
||||||
|
rm -f "$depfile"
|
||||||
|
cat < "$tmpdepfile" > "$depfile"
|
||||||
|
sed '1,2d' "$tmpdepfile" | tr ' ' '
|
||||||
|
' | \
|
||||||
|
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||||
|
## correctly. Breaking it into two sed invocations is a workaround.
|
||||||
|
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||||
|
rm -f "$tmpdepfile" "$tmpdepfile".bak
|
||||||
|
;;
|
||||||
|
|
||||||
|
cpp)
|
||||||
|
# Important note: in order to support this mode, a compiler *must*
|
||||||
|
# always write the 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
|
||||||
|
"$@" -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"
|
||||||
|
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
msvisualcpp)
|
||||||
|
# Important note: in order to support this mode, a compiler *must*
|
||||||
|
# always write the 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")
|
||||||
|
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
|
||||||
|
rm -f "$depfile"
|
||||||
|
echo "$object : \\" > "$depfile"
|
||||||
|
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
|
||||||
|
echo " " >> "$depfile"
|
||||||
|
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
|
||||||
|
rm -f "$tmpdepfile"
|
||||||
|
;;
|
||||||
|
|
||||||
|
none)
|
||||||
|
exec "$@"
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo "Unknown depmode $depmode" 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
exit 0
|
@ -1,8 +0,0 @@
|
|||||||
# Main Makefile for DOSBox
|
|
||||||
|
|
||||||
man_MANS = dosbox.1
|
|
||||||
EXTRA_DIST = $(man_MANS) README.video PORTING
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
44
docs/PORTING
44
docs/PORTING
@ -1,44 +0,0 @@
|
|||||||
Some notes about porting DOSBox to systems with certain restrictions,
|
|
||||||
like handheld devices.
|
|
||||||
|
|
||||||
If memory is a constraint:
|
|
||||||
- in paging.h out-comment the USE_FULL_TLB define to enable special
|
|
||||||
TLB linking code that uses less memory
|
|
||||||
drawback: none (the code is not heavily tested though)
|
|
||||||
gain: reduces memory requirements about ~15mb
|
|
||||||
- in render.h lower the scaler integration:
|
|
||||||
#define RENDER_USE_ADVANCED_SCALERS 1
|
|
||||||
or
|
|
||||||
#define RENDER_USE_ADVANCED_SCALERS 0
|
|
||||||
drawback: complex scalers and the scaler cache are disabled,
|
|
||||||
be sure to test if this affects speed!
|
|
||||||
with define RENDER_USE_ADVANCED_SCALERS==0 most simple
|
|
||||||
scalers are disabled as well, some graphics modes won't
|
|
||||||
work due to reduced cache sizes
|
|
||||||
gain: ~2mb with RENDER_USE_ADVANCED_SCALERS==1
|
|
||||||
~5mb with RENDER_USE_ADVANCED_SCALERS==0
|
|
||||||
- in dos_system.h reduce the drive cache entries:
|
|
||||||
#define MAX_OPENDIRS 256
|
|
||||||
drawback: some apps might not work with large directory trees
|
|
||||||
gain: ~1mb per mounted drive
|
|
||||||
- remove the GUS emulation (gus.cpp, especially GUSRam[1024*1024] )
|
|
||||||
drawback: no gravis ultrasound
|
|
||||||
gain: reduces memory requirements about 1mb
|
|
||||||
- reduce the size of the emulated graphics memory:
|
|
||||||
see the memory sizing in SVGA_Setup_*, especially the defaults
|
|
||||||
in vga_s3.cpp's SVGA_Setup_S3Trio
|
|
||||||
drawback: some graphics modes won't work then
|
|
||||||
gain: reduces memory requirements
|
|
||||||
TODO: fully check this, introduce hard limits
|
|
||||||
|
|
||||||
If speed is a constraint:
|
|
||||||
- see if the simple core is faster, possibly remove the normal core
|
|
||||||
set the simple core as default
|
|
||||||
drawback: one game is known to not work with the simple core;
|
|
||||||
the simple core does only work for games which don't use paging
|
|
||||||
(when paging is requested the normal core is used automatically)
|
|
||||||
gain: the simple core should be somewhat faster
|
|
||||||
TODO: add possibility to easily remove the normal core, use fullcore fallback
|
|
||||||
- raise the default frameskip value
|
|
||||||
drawback: minor graphics smoothness loss for some games (video playback)
|
|
||||||
gain: reduces graphics load
|
|
@ -1,35 +0,0 @@
|
|||||||
Starting with version 0.65, DOSBox allows you to create movies out of screen
|
|
||||||
output.
|
|
||||||
|
|
||||||
To record a movie, you have to press CTRL-ALT-F5.
|
|
||||||
To stop/end the recording, you have to press CTRL-ALT-F5 again.
|
|
||||||
|
|
||||||
To play the recorded movie, you need a movie player which can handle the
|
|
||||||
ZMBV codec. MS Windows users can find this codec in the start menu entry of
|
|
||||||
DOSBox. Users of Linux and other OSes should look for a movie player that
|
|
||||||
uses the ffmpeg libary (you may need to update or ask your distribution to
|
|
||||||
upgrade).
|
|
||||||
|
|
||||||
FAQ:
|
|
||||||
Q: During the display of the movies the sound is lagging.
|
|
||||||
A: Check your display properties to see whether your refresh rate is set to
|
|
||||||
at least 70 hz. Try playing the movie in virtualdub (http://virtualdub.sf.net)
|
|
||||||
|
|
||||||
Q: Why does the resulting movie consist of multiple files?
|
|
||||||
A: Each time the game changes resolution, DOSBox creates a new movie file,
|
|
||||||
because a movie file can only contain one resolution.
|
|
||||||
|
|
||||||
Q: Can I set the cycles higher than my PC can handle during recording?
|
|
||||||
A: Yes. During recording, the game might play slowly and stuttering, but the
|
|
||||||
resulting movie should play at the intended speed and have no stuttering.
|
|
||||||
|
|
||||||
Q: CTRL-ALT-F5 switches to the console under linux.
|
|
||||||
A: 1. Start DOSBox like this: dosbox -startmapper
|
|
||||||
2. Click on Video, click on Add
|
|
||||||
3. Press the key you want (for example scroll lock or printscreen)
|
|
||||||
4. Click exit.
|
|
||||||
5. You can make movies by pressing scroll lock or whichever key you
|
|
||||||
selected.
|
|
||||||
|
|
||||||
Q: The colours are wrong and I'm using 64 bit windows
|
|
||||||
A: Look here: http://vogons.zetafleet.com/viewtopic.php?t=12133
|
|
337
docs/dosbox.1
337
docs/dosbox.1
@ -1,337 +0,0 @@
|
|||||||
.\" Hey, EMACS: -*- nroff -*-
|
|
||||||
.TH DOSBOX 1 "Jul 01, 2007"
|
|
||||||
.\" Please adjust this date whenever revising the manpage.
|
|
||||||
.SH NAME
|
|
||||||
dosbox \- an x86/DOS emulator with sound/graphics
|
|
||||||
.SH SYNOPSIS
|
|
||||||
.B dosbox
|
|
||||||
.B [\-fullscreen]
|
|
||||||
.B [\-startmapper]
|
|
||||||
.B [\-noautoexec]
|
|
||||||
.B [\-securemode]
|
|
||||||
.BI "[\-scaler " scaler ]
|
|
||||||
.BI "[\-forcescaler " scaler ]
|
|
||||||
.BI "[\-conf " configfile ]
|
|
||||||
.BI "[\-lang " langfile ]
|
|
||||||
.B [file]
|
|
||||||
.BI "[\-c " command ]
|
|
||||||
.B [\-exit]
|
|
||||||
.BI "[\-machine " machinetype ]
|
|
||||||
.LP
|
|
||||||
.B dosbox -version
|
|
||||||
.SH DESCRIPTION
|
|
||||||
This manual page briefly documents
|
|
||||||
.BR "dosbox" ", an x86/DOS emulator."
|
|
||||||
.LP
|
|
||||||
.RB "The optional " file " 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:\\.
|
|
||||||
.LP
|
|
||||||
.RI "For an introduction type " INTRO
|
|
||||||
.RB "inside " dosbox .
|
|
||||||
.SH OPTIONS
|
|
||||||
A summary of options is included below.
|
|
||||||
.TP
|
|
||||||
.B \-fullscreen
|
|
||||||
.RB "Start " dosbox " in fullscreen mode."
|
|
||||||
.TP
|
|
||||||
.B \-startmapper
|
|
||||||
.RB "Start the internal keymapper on startup of " dosbox ". You can use it to change the keys " dosbox " uses."
|
|
||||||
.TP
|
|
||||||
.B \-noautoexec
|
|
||||||
Skips the [autoexec] section of the loaded configuration file.
|
|
||||||
.TP
|
|
||||||
.B \-securemode
|
|
||||||
.RB "Same as " \-noautoexec ", but adds " "config.com \-securemode"
|
|
||||||
at the end of
|
|
||||||
.I AUTOEXEC.BAT
|
|
||||||
(which in turn disables any changes to how the drives are mounted
|
|
||||||
.RB "inside " dosbox )
|
|
||||||
.TP
|
|
||||||
.BI \-scaler " scaler"
|
|
||||||
.RI "Uses the graphical scaler specified by " scaler ". See the configuration"
|
|
||||||
file for the available scalers
|
|
||||||
.TP
|
|
||||||
.BI \-forcescaler " scaler"
|
|
||||||
.RB "Similar to the " \-scaler " parameter, but tries to force usage of"
|
|
||||||
the specified scaler even if it might not fit.
|
|
||||||
.TP
|
|
||||||
.BI \-c " command"
|
|
||||||
.RI "Runs the specified " command " before running "
|
|
||||||
.BR file .
|
|
||||||
.RI "Multiple commands can be specified. Each " command " should start with "
|
|
||||||
.BR \-c " though. A command can be:"
|
|
||||||
an Internal Program, a DOS command or an executable on a mounted drive.
|
|
||||||
.TP
|
|
||||||
.BI \-conf " configfile
|
|
||||||
.RB "Start " dosbox " with the options specified in "
|
|
||||||
.IR configfile ". This file has a section in which you can put commands you "
|
|
||||||
wish to execute on startup. Multiple
|
|
||||||
.IR configfiles " can be present at the commandline."
|
|
||||||
.TP
|
|
||||||
.BI \-lang " langfile
|
|
||||||
.RB "Start " dosbox " with the language specified in "
|
|
||||||
.IR langfile .
|
|
||||||
.TP
|
|
||||||
.B \-exit
|
|
||||||
.BR dosbox " will close itself when the DOS program specified by "file " ends."
|
|
||||||
.TP
|
|
||||||
.BI \-machine " machinetype
|
|
||||||
.RB "Setup " dosbox " to emulate a specific type of machine."
|
|
||||||
.RI "Valid choices are: " "hercules, cga, pcjr, tandy, vga(default)".
|
|
||||||
The machinetype has influence on both the videocard and the available
|
|
||||||
soundcards.
|
|
||||||
.TP
|
|
||||||
.B \-version
|
|
||||||
Output version information and exit. Useful for frontends.
|
|
||||||
.SH "INTERNAL COMMANDS"
|
|
||||||
.B dosbox
|
|
||||||
supports most of the DOS commands found in command.com. In addition, the
|
|
||||||
following extra commands are available:
|
|
||||||
.HP
|
|
||||||
.BI "MOUNT [\-t " type "] [\-size " size ]
|
|
||||||
.I driveletter sourcedirectory
|
|
||||||
.B [\-ioctl]
|
|
||||||
.BI "[\-usecd " number "] [\-label " drivelabel "] [\-freesize " freesize ]
|
|
||||||
.LP
|
|
||||||
.B MOUNT \-cd
|
|
||||||
.LP
|
|
||||||
.B MOUNT \-u driveletter
|
|
||||||
.LP
|
|
||||||
.RB "Program to mount local directories as drives inside " dosbox .
|
|
||||||
.RS
|
|
||||||
.TP
|
|
||||||
.I driveletter
|
|
||||||
The driveletter inside dosbox (eg. C).
|
|
||||||
.TP
|
|
||||||
.I sourcedirectory
|
|
||||||
The local directory you want to have inside dosbox.
|
|
||||||
.TP
|
|
||||||
.BI \-t " type"
|
|
||||||
Type of the mounted directory. Supported are: dir (standard), floppy, cdrom.
|
|
||||||
.TP
|
|
||||||
.BI \-size " drivesize"
|
|
||||||
Sets the size of the drive. See the examples in the README for details.
|
|
||||||
.TP
|
|
||||||
.BI \-freesize " size_in_mb"
|
|
||||||
Sets the amount of free space available on a drive in MB's. This is a more
|
|
||||||
.RB "simple version of " \-size .
|
|
||||||
.TP
|
|
||||||
.BI \-label " drivelabel"
|
|
||||||
.RI "Sets the name of the drive to " drivelabel ". Needed on some"
|
|
||||||
systems if the cd label isn't read correctly. Useful when a
|
|
||||||
program can't find its cdrom. If you don't specify a label and no
|
|
||||||
.RB "lowlevel support is selected (" "\-usecd #" " and/or " "\-ioctl/aspi" "):"
|
|
||||||
.RS
|
|
||||||
.LP
|
|
||||||
For win32: label is extracted from "Real Drive".
|
|
||||||
.TP
|
|
||||||
For Linux: label is set to NO_LABEL.
|
|
||||||
.TP
|
|
||||||
If you do specify a label this label will be kept as long as the drive
|
|
||||||
is mounted. It will not be updated !!
|
|
||||||
.RE
|
|
||||||
.TP
|
|
||||||
.B \-ioctl
|
|
||||||
Forces to use ioctl commands.
|
|
||||||
.TP
|
|
||||||
.BI \-usecd " number"
|
|
||||||
Forces to use SDL cdrom support for drive number.
|
|
||||||
.IR Number " can be found by "
|
|
||||||
.BR \-cd ".
|
|
||||||
.TP
|
|
||||||
.B \-cd
|
|
||||||
.RB "Displays all detected cdrom drives and their numbers. Use with " \-usecd "."
|
|
||||||
.TP
|
|
||||||
.B \-u
|
|
||||||
Unmounts a mounted drive. Doesn't work on virtual Drives (like Z:\\)
|
|
||||||
.RE
|
|
||||||
.PP
|
|
||||||
.B "Example:"
|
|
||||||
.TP
|
|
||||||
.RB "To mount your /home/dos/dosgames directory as C drive in " dosbox :
|
|
||||||
.RS
|
|
||||||
mount c /home/dos/dosgames
|
|
||||||
.RE
|
|
||||||
.TP
|
|
||||||
.B MEM
|
|
||||||
.LP
|
|
||||||
Display the amount of free memory
|
|
||||||
.TP
|
|
||||||
.B CONFIG [\-writeconf] [\-writelang] file
|
|
||||||
.LP
|
|
||||||
.B CONFIG -securemode
|
|
||||||
.LP
|
|
||||||
.RB "Write the current configuration or language settings to " file ,
|
|
||||||
which is located on the local filesystem. Not a mounted drive in
|
|
||||||
.BR dosbox .
|
|
||||||
.TP
|
|
||||||
.B \-securemode
|
|
||||||
.RB Switches dosbox " to a more secure mode. In this mode the"
|
|
||||||
.RI "internal commands " MOUNT ", " IMGMOUNT " and " BOOT " won\'t work."
|
|
||||||
It\'s not possible
|
|
||||||
either to create a new configfile or languagefile in this mode.
|
|
||||||
(Warning you can only undo this mode by restarting
|
|
||||||
.BR dosbox .)
|
|
||||||
.LP
|
|
||||||
The configuration file controls various settings of
|
|
||||||
.BR dosbox ": The amount of emulated memory,"
|
|
||||||
the emulated soundcards and many
|
|
||||||
.RI "more things. It futher allows acces to " AUTOEXEC.BAT .
|
|
||||||
.LP
|
|
||||||
The language file controls all visible ouput of the internal commands and
|
|
||||||
the internal dos.
|
|
||||||
.RB "See the section " FILES " for more information."
|
|
||||||
.TP
|
|
||||||
.B LOADFIX [\-size] [programname] [parameters]
|
|
||||||
.LP
|
|
||||||
.B LOADFIX \-f
|
|
||||||
.LP
|
|
||||||
Program to reduce the amount of memory available. Useful for old programs which don't expect much memory to be free.
|
|
||||||
.RS
|
|
||||||
.TP
|
|
||||||
.B [programname]
|
|
||||||
The name of the program which is executed after loadfix eats up its memory.
|
|
||||||
.TP
|
|
||||||
.B [parameters]
|
|
||||||
.RB "Parameters given to the " programname " executable."
|
|
||||||
.TP
|
|
||||||
.B \-size
|
|
||||||
The amount of memory to eat up (in kb). Example -32, -64 or -128
|
|
||||||
.TP
|
|
||||||
.B \-f
|
|
||||||
Frees all memory eaten up by loadfix.
|
|
||||||
.RE
|
|
||||||
.TP
|
|
||||||
.B RESCAN
|
|
||||||
.LP
|
|
||||||
.RB "Make " dosbox " reread the directory structure. Useful if you changed
|
|
||||||
.RB "something on a mounted drive outside " dosbox ".(CTRL\-F4 does"
|
|
||||||
this as well!)
|
|
||||||
.TP
|
|
||||||
.B IMGMOUNT
|
|
||||||
.LP
|
|
||||||
.RB "A utility to mount disk images and CD-ROM images in " dosbox .
|
|
||||||
.TP
|
|
||||||
.RB "Read the " README " of " dosbox " for the full and correct syntax."
|
|
||||||
.RE
|
|
||||||
.TP
|
|
||||||
.B BOOT
|
|
||||||
.LP
|
|
||||||
Boot will start floppy images or hard disk images independent of the
|
|
||||||
.RB "operating system emulation offered by " dosbox ". This will allow you to play booter floppies or boot to other operating systems inside " dosbox .
|
|
||||||
.TP
|
|
||||||
.RB "Read the " README " of " dosbox " for the full and correct syntax."
|
|
||||||
.RE
|
|
||||||
.TP
|
|
||||||
.B IPX
|
|
||||||
.LP
|
|
||||||
.RB "You need to enable IPX networking in the configuration file of " dosbox .
|
|
||||||
.RB "All of the IPX networking is managed through the internal " dosbox " program
|
|
||||||
.BR IPXNET ". For help on the IPX networking from inside " dosbox ", type"
|
|
||||||
.BR "IPXNET HELP" " and the program will list out the commands and relevant documentation."
|
|
||||||
.TP
|
|
||||||
.RB "Read the " README " of " dosbox " for the full and correct syntax."
|
|
||||||
.RE
|
|
||||||
.TP
|
|
||||||
.B KEYB
|
|
||||||
.LP
|
|
||||||
Keyb can change the keyboardlayout and the codepage used inside dosbox.
|
|
||||||
.TP
|
|
||||||
.RB "Read the " README " of " dosbox " for the full and correct syntax."
|
|
||||||
.RE
|
|
||||||
.SH FILES
|
|
||||||
Configuration and language files use a format similar to Windows .ini files.
|
|
||||||
First ~/.dosboxrc (if present) will be loaded. If no
|
|
||||||
configfile is specified at the commandline, a file named
|
|
||||||
.BR dosbox.conf " (if present in the current directory) will be"
|
|
||||||
loaded automatically afterwards. If a configfile is specified at the commandline
|
|
||||||
that one will be used instead.
|
|
||||||
.SH "SPECIAL KEYS"
|
|
||||||
.TP 12m
|
|
||||||
.IP ALT\-ENTER
|
|
||||||
Go full screen and back.
|
|
||||||
.IP ALT\-PAUSE
|
|
||||||
Pause emulation.
|
|
||||||
.IP CTRL\-F1
|
|
||||||
Start the keymapper.
|
|
||||||
.IP CTRL\-ALT\-F5
|
|
||||||
Start/Stop creating a movie of the screen.
|
|
||||||
.IP CTRL\-F4
|
|
||||||
Swap mounted disk-image (Only used with imgmount). Update directory cache
|
|
||||||
for all drives!
|
|
||||||
.IP CTRL\-F5
|
|
||||||
Save a screenshot.(png)
|
|
||||||
.IP CTRL\-F6
|
|
||||||
Start/Stop recording sound output to a wave file.
|
|
||||||
.IP CTRL\-ALT\-F7
|
|
||||||
Start/Stop recording of OPL commands.
|
|
||||||
.IP CTRL\-ALT\-F8
|
|
||||||
Start/Stop the recording of raw MIDI commands.
|
|
||||||
.IP CTRL\-F7
|
|
||||||
Decrease frameskip.
|
|
||||||
.IP CTRL\-F8
|
|
||||||
Increase frameskip.
|
|
||||||
.IP CTRL\-F9
|
|
||||||
Kill dosbox.
|
|
||||||
.IP CTRL\-F10
|
|
||||||
Capture/Release the mouse.
|
|
||||||
.IP CTRL\-F11
|
|
||||||
Slow down emulation (Increase dosbox Cycles).
|
|
||||||
.IP CTRL\-F12
|
|
||||||
Speed up emulation (Decrease dosbox Cycles).
|
|
||||||
.IP ALT\-F12
|
|
||||||
Unlock speed (turbo button).
|
|
||||||
.PP
|
|
||||||
These are the default keybindings. They can be changed in the keymapper.
|
|
||||||
.PP
|
|
||||||
Saved/recorded files can be found in current_directory/capture
|
|
||||||
(can be changed in the configfile).
|
|
||||||
.RB "The directory has to exist prior to starting " dosbox " else nothing"
|
|
||||||
gets saved/recorded !
|
|
||||||
.PP
|
|
||||||
.BR "Note: " "Once you increase your " dosbox " cycles beyond your computer's maximum
|
|
||||||
capacity, it will produce the same effect as slowing down the emulation.
|
|
||||||
This maximum will vary from computer to computer, there is no standard.
|
|
||||||
.SH "SYSTEM REQUIREMENTS"
|
|
||||||
Fast machine. My guess would be pentium\-2 400+ to get decent emulation
|
|
||||||
of games written for an 286 machine.
|
|
||||||
For protected mode games a 1 Ghz machine is recommended and don't expect
|
|
||||||
them to run fast though!! Be sure to read the next section on how to speed
|
|
||||||
it up somewhat.
|
|
||||||
.SS "To run resource\-demanding games"
|
|
||||||
.BR dosbox " emulates the CPU, the sound and graphic cards, and some other"
|
|
||||||
.RB " 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 various utils (top). Once 100% of your real CPU time is
|
|
||||||
.RB "used there is no further way to speed up " dosbox " unless you reduce the load"
|
|
||||||
.RB "generated by the non\-CPU parts of " dosbox .
|
|
||||||
.PP
|
|
||||||
So:
|
|
||||||
.PP
|
|
||||||
.RB "Close every program but " dosbox .
|
|
||||||
.PP
|
|
||||||
.RB "Overclock " dosbox " until 100% of your CPU is used.(CTRL\-F12)"
|
|
||||||
.PP
|
|
||||||
.RB "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 CTRL\-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.
|
|
||||||
.SH NOTES
|
|
||||||
.RB "While we hope that, one day, " dosbox " will run virtually all programs ever made for the PC..."
|
|
||||||
.RB "we are not there yet. At present, " dosbox " run on a 1.7 Gigahertz PC is roughly the equivalent of a 25MHz 386 PC."
|
|
||||||
While the 0.60 release has added support for "protected mode" allowing for more complex and recent programs,
|
|
||||||
but note that this support is early in development and nowhere near as complete as the support for 386 real\-mode
|
|
||||||
games (or earlier). Also note that "protected mode" games need substantially more resources and may
|
|
||||||
.RB "require a much faster processor for you to run it properly in " dosbox .
|
|
||||||
.SH BUGS
|
|
||||||
Not all DOS programs work properly.
|
|
||||||
.BR dosbox " will exit without warning if an error occurred."
|
|
||||||
.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,10 +1,8 @@
|
|||||||
noinst_HEADERS = \
|
noinst_HEADERS = \
|
||||||
bios.h \
|
bios.h \
|
||||||
bios_disk.h \
|
|
||||||
callback.h \
|
callback.h \
|
||||||
cpu.h \
|
cpu.h \
|
||||||
cross.h \
|
cross.h \
|
||||||
control.h \
|
|
||||||
debug.h \
|
debug.h \
|
||||||
dma.h \
|
dma.h \
|
||||||
dos_inc.h \
|
dos_inc.h \
|
||||||
@ -14,26 +12,18 @@ fpu.h \
|
|||||||
hardware.h \
|
hardware.h \
|
||||||
inout.h \
|
inout.h \
|
||||||
joystick.h \
|
joystick.h \
|
||||||
ipx.h \
|
|
||||||
ipxserver.h \
|
|
||||||
keyboard.h \
|
keyboard.h \
|
||||||
logging.h \
|
|
||||||
mapper.h \
|
|
||||||
mem.h \
|
mem.h \
|
||||||
mixer.h \
|
mixer.h \
|
||||||
modules.h \
|
modules.h \
|
||||||
mouse.h \
|
mouse.h \
|
||||||
paging.h \
|
|
||||||
pic.h \
|
pic.h \
|
||||||
programs.h \
|
programs.h \
|
||||||
render.h \
|
render.h \
|
||||||
regs.h \
|
regs.h \
|
||||||
render.h \
|
render.h \
|
||||||
serialport.h \
|
|
||||||
setup.h \
|
setup.h \
|
||||||
shell.h \
|
|
||||||
support.h \
|
support.h \
|
||||||
timer.h \
|
timer.h \
|
||||||
vga.h \
|
|
||||||
video.h
|
video.h
|
||||||
|
|
||||||
|
269
include/Makefile.in
Normal file
269
include/Makefile.in
Normal file
@ -0,0 +1,269 @@
|
|||||||
|
# Makefile.in generated by automake 1.6.1 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@
|
||||||
|
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_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@
|
||||||
|
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@
|
||||||
|
noinst_HEADERS = \
|
||||||
|
bios.h \
|
||||||
|
callback.h \
|
||||||
|
cpu.h \
|
||||||
|
cross.h \
|
||||||
|
debug.h \
|
||||||
|
dma.h \
|
||||||
|
dos_inc.h \
|
||||||
|
dos_system.h \
|
||||||
|
dosbox.h \
|
||||||
|
fpu.h \
|
||||||
|
hardware.h \
|
||||||
|
inout.h \
|
||||||
|
joystick.h \
|
||||||
|
keyboard.h \
|
||||||
|
mem.h \
|
||||||
|
mixer.h \
|
||||||
|
modules.h \
|
||||||
|
mouse.h \
|
||||||
|
pic.h \
|
||||||
|
programs.h \
|
||||||
|
render.h \
|
||||||
|
regs.h \
|
||||||
|
render.h \
|
||||||
|
setup.h \
|
||||||
|
support.h \
|
||||||
|
timer.h \
|
||||||
|
video.h
|
||||||
|
|
||||||
|
subdir = include
|
||||||
|
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||||
|
CONFIG_HEADER = $(top_builddir)/config.h
|
||||||
|
CONFIG_CLEAN_FILES =
|
||||||
|
DIST_SOURCES =
|
||||||
|
HEADERS = $(noinst_HEADERS)
|
||||||
|
|
||||||
|
DIST_COMMON = $(noinst_HEADERS) Makefile.am Makefile.in
|
||||||
|
all: all-am
|
||||||
|
|
||||||
|
.SUFFIXES:
|
||||||
|
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
|
||||||
|
cd $(top_srcdir) && \
|
||||||
|
$(AUTOMAKE) --gnits include/Makefile
|
||||||
|
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||||
|
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
|
||||||
|
uninstall-info-am:
|
||||||
|
|
||||||
|
ETAGS = etags
|
||||||
|
ETAGSFLAGS =
|
||||||
|
|
||||||
|
tags: TAGS
|
||||||
|
|
||||||
|
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||||
|
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||||
|
unique=`for i in $$list; do \
|
||||||
|
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||||
|
done | \
|
||||||
|
$(AWK) ' { files[$$0] = 1; } \
|
||||||
|
END { for (i in files) print i; }'`; \
|
||||||
|
mkid -fID $$unique
|
||||||
|
|
||||||
|
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||||
|
$(TAGS_FILES) $(LISP)
|
||||||
|
tags=; \
|
||||||
|
here=`pwd`; \
|
||||||
|
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||||
|
unique=`for i in $$list; do \
|
||||||
|
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||||
|
done | \
|
||||||
|
$(AWK) ' { files[$$0] = 1; } \
|
||||||
|
END { for (i in files) print i; }'`; \
|
||||||
|
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|
||||||
|
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||||
|
$$tags $$unique
|
||||||
|
|
||||||
|
GTAGS:
|
||||||
|
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||||
|
&& cd $(top_srcdir) \
|
||||||
|
&& gtags -i $(GTAGS_ARGS) $$here
|
||||||
|
|
||||||
|
distclean-tags:
|
||||||
|
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH
|
||||||
|
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||||
|
|
||||||
|
top_distdir = ..
|
||||||
|
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
|
||||||
|
|
||||||
|
distdir: $(DISTFILES)
|
||||||
|
@for file in $(DISTFILES); 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 $(HEADERS)
|
||||||
|
|
||||||
|
installdirs:
|
||||||
|
|
||||||
|
install: install-am
|
||||||
|
install-exec: install-exec-am
|
||||||
|
install-data: install-data-am
|
||||||
|
uninstall: uninstall-am
|
||||||
|
|
||||||
|
install-am: all-am
|
||||||
|
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||||
|
|
||||||
|
installcheck: installcheck-am
|
||||||
|
install-strip:
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||||
|
INSTALL_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) stamp-h stamp-h[0-9]*
|
||||||
|
|
||||||
|
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 distclean-tags
|
||||||
|
|
||||||
|
dvi: dvi-am
|
||||||
|
|
||||||
|
dvi-am:
|
||||||
|
|
||||||
|
info: info-am
|
||||||
|
|
||||||
|
info-am:
|
||||||
|
|
||||||
|
install-data-am:
|
||||||
|
|
||||||
|
install-exec-am:
|
||||||
|
|
||||||
|
install-info: install-info-am
|
||||||
|
|
||||||
|
install-man:
|
||||||
|
|
||||||
|
installcheck-am:
|
||||||
|
|
||||||
|
maintainer-clean: maintainer-clean-am
|
||||||
|
|
||||||
|
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||||
|
|
||||||
|
mostlyclean: mostlyclean-am
|
||||||
|
|
||||||
|
mostlyclean-am: mostlyclean-generic
|
||||||
|
|
||||||
|
uninstall-am: uninstall-info-am
|
||||||
|
|
||||||
|
.PHONY: GTAGS all all-am check check-am clean clean-generic distclean \
|
||||||
|
distclean-generic distclean-tags distdir dvi dvi-am info \
|
||||||
|
info-am install install-am install-data install-data-am \
|
||||||
|
install-exec install-exec-am install-info install-info-am \
|
||||||
|
install-man install-strip installcheck installcheck-am \
|
||||||
|
installdirs maintainer-clean maintainer-clean-generic \
|
||||||
|
mostlyclean mostlyclean-generic tags uninstall uninstall-am \
|
||||||
|
uninstall-info-am
|
||||||
|
|
||||||
|
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||||
|
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||||
|
.NOEXPORT:
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2007 The DOSBox Team
|
* Copyright (C) 2002 The DOSBox Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -9,16 +9,13 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Library General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef DOSBOX_BIOS_H
|
|
||||||
#define DOSBOX_BIOS_H
|
|
||||||
|
|
||||||
#define BIOS_BASE_ADDRESS_COM1 0x400
|
#define BIOS_BASE_ADDRESS_COM1 0x400
|
||||||
#define BIOS_BASE_ADDRESS_COM2 0x402
|
#define BIOS_BASE_ADDRESS_COM2 0x402
|
||||||
#define BIOS_BASE_ADDRESS_COM3 0x404
|
#define BIOS_BASE_ADDRESS_COM3 0x404
|
||||||
@ -30,7 +27,6 @@
|
|||||||
#define BIOS_CONFIGURATION 0x410
|
#define BIOS_CONFIGURATION 0x410
|
||||||
/* 0x412 is reserved */
|
/* 0x412 is reserved */
|
||||||
#define BIOS_MEMORY_SIZE 0x413
|
#define BIOS_MEMORY_SIZE 0x413
|
||||||
#define BIOS_TRUE_MEMORY_SIZE 0x415
|
|
||||||
/* #define bios_expansion_memory_size (*(unsigned int *) 0x415) */
|
/* #define bios_expansion_memory_size (*(unsigned int *) 0x415) */
|
||||||
#define BIOS_KEYBOARD_STATE 0x417
|
#define BIOS_KEYBOARD_STATE 0x417
|
||||||
#define BIOS_KEYBOARD_FLAGS1 BIOS_KEYBOARD_STATE
|
#define BIOS_KEYBOARD_FLAGS1 BIOS_KEYBOARD_STATE
|
||||||
@ -43,7 +39,7 @@
|
|||||||
/* #define bios_keyboard_buffer (*(unsigned int *) 0x41e) */
|
/* #define bios_keyboard_buffer (*(unsigned int *) 0x41e) */
|
||||||
#define BIOS_DRIVE_ACTIVE 0x43e
|
#define BIOS_DRIVE_ACTIVE 0x43e
|
||||||
#define BIOS_DRIVE_RUNNING 0x43f
|
#define BIOS_DRIVE_RUNNING 0x43f
|
||||||
#define BIOS_DISK_MOTOR_TIMEOUT 0x440
|
#define BIOS_MOTOR_NACHLAUFZEIT 0x440
|
||||||
#define BIOS_DISK_STATUS 0x441
|
#define BIOS_DISK_STATUS 0x441
|
||||||
/* #define bios_fdc_result_buffer (*(unsigned short *) 0x442) */
|
/* #define bios_fdc_result_buffer (*(unsigned short *) 0x442) */
|
||||||
#define BIOS_VIDEO_MODE 0x449
|
#define BIOS_VIDEO_MODE 0x449
|
||||||
@ -73,9 +69,7 @@
|
|||||||
/* 0x47b is reserved */
|
/* 0x47b is reserved */
|
||||||
#define BIOS_COM1_TIMEOUT 0x47c
|
#define BIOS_COM1_TIMEOUT 0x47c
|
||||||
#define BIOS_COM2_TIMEOUT 0x47d
|
#define BIOS_COM2_TIMEOUT 0x47d
|
||||||
#define BIOS_COM3_TIMEOUT 0x47e
|
/* 0x47e is reserved */
|
||||||
#define BIOS_COM4_TIMEOUT 0x47f
|
|
||||||
/* 0x47e is reserved */ //<- why that?
|
|
||||||
/* 0x47f-0x4ff is unknow for me */
|
/* 0x47f-0x4ff is unknow for me */
|
||||||
#define BIOS_KEYBOARD_BUFFER_START 0x480
|
#define BIOS_KEYBOARD_BUFFER_START 0x480
|
||||||
#define BIOS_KEYBOARD_BUFFER_END 0x482
|
#define BIOS_KEYBOARD_BUFFER_END 0x482
|
||||||
@ -90,26 +84,31 @@
|
|||||||
|
|
||||||
#define BIOS_KEYBOARD_FLAGS3 0x496
|
#define BIOS_KEYBOARD_FLAGS3 0x496
|
||||||
#define BIOS_KEYBOARD_LEDS 0x497
|
#define BIOS_KEYBOARD_LEDS 0x497
|
||||||
|
|
||||||
#define BIOS_WAIT_FLAG_POINTER 0x498
|
|
||||||
#define BIOS_WAIT_FLAG_COUNT 0x49c
|
|
||||||
#define BIOS_WAIT_FLAG_ACTIVE 0x4a0
|
|
||||||
#define BIOS_WAIT_FLAG_TEMP 0x4a1
|
|
||||||
|
|
||||||
|
|
||||||
#define BIOS_PRINT_SCREEN_FLAG 0x500
|
#define BIOS_PRINT_SCREEN_FLAG 0x500
|
||||||
|
|
||||||
#define BIOS_VIDEO_SAVEPTR 0x4a8
|
#define BIOS_VIDEO_SAVEPTR 0x4a8
|
||||||
|
|
||||||
/* maximum of scancodes handled by keyboard bios routines */
|
|
||||||
#define MAX_SCAN_CODE 0x58
|
|
||||||
|
|
||||||
/* The Section handling Bios Disk Access */
|
/* The Section handling Bios Disk Access */
|
||||||
//#define BIOS_MAX_DISK 10
|
#define BIOS_MAX_DISK 10
|
||||||
|
|
||||||
|
class BIOS_Disk {
|
||||||
|
public:
|
||||||
|
virtual Bit8u Read_Sector(Bit8u * count,Bit8u head,Bit16u cylinder,Bit16u sector,Bit8u * data)=0;
|
||||||
|
virtual Bit8u Write_Sector(Bit8u * count,Bit8u head,Bit16u cylinder,Bit16u sector,Bit8u * data)=0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class imageDisk : public BIOS_Disk {
|
||||||
|
public:
|
||||||
|
Bit8u Read_Sector(Bit8u * count,Bit8u head,Bit16u cylinder,Bit16u sector,Bit8u * data);
|
||||||
|
Bit8u Write_Sector(Bit8u * count,Bit8u head,Bit16u cylinder,Bit16u sector,Bit8u * data);
|
||||||
|
imageDisk(char * file);
|
||||||
|
private:
|
||||||
|
Bit16u sector_size;
|
||||||
|
Bit16u heads,cylinders,sectors;
|
||||||
|
Bit8u * image;
|
||||||
|
};
|
||||||
|
|
||||||
//#define MAX_SWAPPABLE_DISKS 20
|
|
||||||
|
|
||||||
void BIOS_ZeroExtendedSize(bool in);
|
|
||||||
void char_out(Bit8u chr,Bit32u att,Bit8u page);
|
void char_out(Bit8u chr,Bit32u att,Bit8u page);
|
||||||
void INT10_StartUp(void);
|
void INT10_StartUp(void);
|
||||||
void INT16_StartUp(void);
|
void INT16_StartUp(void);
|
||||||
@ -118,10 +117,4 @@ void INT2F_StartUp(void);
|
|||||||
void INT33_StartUp(void);
|
void INT33_StartUp(void);
|
||||||
void INT13_StartUp(void);
|
void INT13_StartUp(void);
|
||||||
|
|
||||||
bool BIOS_AddKeyToBuffer(Bit16u code);
|
|
||||||
|
|
||||||
void INT10_ReloadRomFonts();
|
|
||||||
|
|
||||||
void BIOS_SetComPorts (Bit16u baseaddr[]);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
@ -1,85 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2002-2008 The DOSBox Team
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef DOSBOX_BIOS_DISK_H
|
|
||||||
#define DOSBOX_BIOS_DISK_H
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#ifndef DOSBOX_MEM_H
|
|
||||||
#include "mem.h"
|
|
||||||
#endif
|
|
||||||
#ifndef DOSBOX_DOS_INC_H
|
|
||||||
#include "dos_inc.h"
|
|
||||||
#endif
|
|
||||||
#ifndef DOSBOX_BIOS_H
|
|
||||||
#include "bios.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* The Section handling Bios Disk Access */
|
|
||||||
#define BIOS_MAX_DISK 10
|
|
||||||
|
|
||||||
#define MAX_SWAPPABLE_DISKS 20
|
|
||||||
struct diskGeo {
|
|
||||||
Bit32u ksize; /* Size in kilobytes */
|
|
||||||
Bit16u secttrack; /* Sectors per track */
|
|
||||||
Bit16u headscyl; /* Heads per cylinder */
|
|
||||||
Bit16u cylcount; /* Cylinders per side */
|
|
||||||
Bit16u biosval; /* Type to return from BIOS */
|
|
||||||
};
|
|
||||||
extern diskGeo DiskGeometryList[];
|
|
||||||
|
|
||||||
class imageDisk {
|
|
||||||
public:
|
|
||||||
Bit8u Read_Sector(Bit32u head,Bit32u cylinder,Bit32u sector,void * data);
|
|
||||||
Bit8u Write_Sector(Bit32u head,Bit32u cylinder,Bit32u sector,void * data);
|
|
||||||
Bit8u Read_AbsoluteSector(Bit32u sectnum, void * data);
|
|
||||||
Bit8u Write_AbsoluteSector(Bit32u sectnum, void * data);
|
|
||||||
|
|
||||||
void Set_Geometry(Bit32u setHeads, Bit32u setCyl, Bit32u setSect, Bit32u setSectSize);
|
|
||||||
void Get_Geometry(Bit32u * getHeads, Bit32u *getCyl, Bit32u *getSect, Bit32u *getSectSize);
|
|
||||||
Bit8u GetBiosType(void);
|
|
||||||
Bit32u getSectSize(void);
|
|
||||||
imageDisk(FILE *imgFile, Bit8u *imgName, Bit32u imgSizeK, bool isHardDisk);
|
|
||||||
~imageDisk() { if(diskimg != NULL) { fclose(diskimg); } };
|
|
||||||
|
|
||||||
bool hardDrive;
|
|
||||||
bool active;
|
|
||||||
FILE *diskimg;
|
|
||||||
Bit8u diskname[512];
|
|
||||||
Bit8u floppytype;
|
|
||||||
|
|
||||||
Bit32u sector_size;
|
|
||||||
Bit32u heads,cylinders,sectors;
|
|
||||||
};
|
|
||||||
|
|
||||||
void updateDPT(void);
|
|
||||||
|
|
||||||
#define MAX_HDD_IMAGES 2
|
|
||||||
|
|
||||||
extern imageDisk *imageDiskList[2 + MAX_HDD_IMAGES];
|
|
||||||
extern imageDisk *diskSwap[20];
|
|
||||||
extern Bits swapPosition;
|
|
||||||
extern Bit16u imgDTASeg; /* Real memory location of temporary DTA pointer for fat image disk access */
|
|
||||||
extern RealPt imgDTAPtr; /* Real memory location of temporary DTA pointer for fat image disk access */
|
|
||||||
extern DOS_DTA *imgDTA;
|
|
||||||
|
|
||||||
void swapInDisks(void);
|
|
||||||
void swapInNextDisk(void);
|
|
||||||
bool getSwapRequest(void);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2007 The DOSBox Team
|
* Copyright (C) 2002 The DOSBox Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -9,49 +9,33 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Library General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: callback.h,v 1.23 2009/04/25 16:25:03 harekiet Exp $ */
|
#ifndef __CALLBACK_H
|
||||||
|
#define __CALLBACK_H
|
||||||
|
|
||||||
#ifndef DOSBOX_CALLBACK_H
|
#include <mem.h>
|
||||||
#define DOSBOX_CALLBACK_H
|
|
||||||
|
|
||||||
#ifndef DOSBOX_MEM_H
|
|
||||||
#include "mem.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef Bitu (*CallBack_Handler)(void);
|
typedef Bitu (*CallBack_Handler)(void);
|
||||||
extern CallBack_Handler CallBack_Handlers[];
|
extern CallBack_Handler CallBack_Handlers[];
|
||||||
|
|
||||||
enum { CB_RETN,CB_RETF,CB_RETF8,CB_IRET,CB_IRETD,CB_IRET_STI,CB_IRET_EOI_PIC1,
|
enum { CB_RETF,CB_IRET };
|
||||||
CB_IRQ0,CB_IRQ1,CB_IRQ9,CB_IRQ12,CB_IRQ12_RET,CB_IRQ6_PCJR,CB_MOUSE,
|
|
||||||
CB_INT29,CB_INT16,CB_HOOKABLE,CB_TDE_IRET,CB_IPXESR,CB_IPXESR_RET,
|
|
||||||
CB_INT21 };
|
|
||||||
|
|
||||||
#define CB_MAX 128
|
#define CB_MAX 1024
|
||||||
#define CB_SIZE 32
|
#define CB_SEG 0xC800
|
||||||
#define CB_SEG 0xF100
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
CBRET_NONE=0,CBRET_STOP=1
|
CBRET_NONE=0,CBRET_STOP=1
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Bit8u lastint;
|
extern Bit8u lastint;
|
||||||
|
INLINE RealPt CALLBACK_RealPointer(Bitu callback) {
|
||||||
static INLINE RealPt CALLBACK_RealPointer(Bitu callback) {
|
return RealMake(CB_SEG,callback << 4);
|
||||||
return RealMake(CB_SEG,(Bit16u)(callback*CB_SIZE));
|
|
||||||
}
|
|
||||||
static INLINE PhysPt CALLBACK_PhysPointer(Bitu callback) {
|
|
||||||
return PhysMake(CB_SEG,(Bit16u)(callback*CB_SIZE));
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE PhysPt CALLBACK_GetBase(void) {
|
|
||||||
return CB_SEG << 4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Bitu CALLBACK_Allocate();
|
Bitu CALLBACK_Allocate();
|
||||||
@ -62,38 +46,11 @@ void CALLBACK_Idle(void);
|
|||||||
void CALLBACK_RunRealInt(Bit8u intnum);
|
void CALLBACK_RunRealInt(Bit8u intnum);
|
||||||
void CALLBACK_RunRealFar(Bit16u seg,Bit16u off);
|
void CALLBACK_RunRealFar(Bit16u seg,Bit16u off);
|
||||||
|
|
||||||
bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,const char* descr);
|
bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type);
|
||||||
Bitu CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,PhysPt addr,const char* descr);
|
|
||||||
|
|
||||||
const char* CALLBACK_GetDescription(Bitu callback);
|
|
||||||
bool CALLBACK_Free(Bitu callback);
|
bool CALLBACK_Free(Bitu callback);
|
||||||
|
|
||||||
void CALLBACK_SCF(bool val);
|
void CALLBACK_SCF(bool val);
|
||||||
void CALLBACK_SZF(bool val);
|
void CALLBACK_SZF(bool val);
|
||||||
|
|
||||||
extern Bitu call_priv_io;
|
|
||||||
|
|
||||||
|
|
||||||
class CALLBACK_HandlerObject{
|
|
||||||
private:
|
|
||||||
bool installed;
|
|
||||||
Bit16u m_callback;
|
|
||||||
enum {NONE,SETUP,SETUPAT} m_type;
|
|
||||||
struct {
|
|
||||||
RealPt old_vector;
|
|
||||||
Bit8u interrupt;
|
|
||||||
bool installed;
|
|
||||||
} vectorhandler;
|
|
||||||
public:
|
|
||||||
CALLBACK_HandlerObject():installed(false),m_type(NONE){vectorhandler.installed=false;}
|
|
||||||
~CALLBACK_HandlerObject();
|
|
||||||
//Install and allocate a callback.
|
|
||||||
void Install(CallBack_Handler handler,Bitu type,const char* description);
|
|
||||||
void Install(CallBack_Handler handler,Bitu type,PhysPt addr,const char* description);
|
|
||||||
//Only allocate a callback number
|
|
||||||
void Allocate(CallBack_Handler handler,const char* description=0);
|
|
||||||
Bit16u Get_callback(){return m_callback;}
|
|
||||||
RealPt Get_RealPointer(){ return CALLBACK_RealPointer(m_callback);}
|
|
||||||
void Set_RealVec(Bit8u vec);
|
|
||||||
};
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1,87 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2002-2008 The DOSBox Team
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* $Id: control.h,v 1.1 2009/02/01 14:11:45 qbix79 Exp $ */
|
|
||||||
|
|
||||||
#ifndef DOSBOX_CONTROL_H
|
|
||||||
#define DOSBOX_CONTROL_H
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning ( disable : 4786 )
|
|
||||||
#pragma warning ( disable : 4290 )
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef DOSBOX_PROGRAMS_H
|
|
||||||
#include "programs.h"
|
|
||||||
#endif
|
|
||||||
#ifndef DOSBOX_SETUP_H
|
|
||||||
#include "setup.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CH_LIST
|
|
||||||
#define CH_LIST
|
|
||||||
#include <list>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CH_VECTOR
|
|
||||||
#define CH_VECTOR
|
|
||||||
#include <vector>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CH_STRING
|
|
||||||
#define CH_STRING
|
|
||||||
#include <string>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Config{
|
|
||||||
public:
|
|
||||||
CommandLine * cmdline;
|
|
||||||
private:
|
|
||||||
std::list<Section*> sectionlist;
|
|
||||||
typedef std::list<Section*>::iterator it;
|
|
||||||
typedef std::list<Section*>::reverse_iterator reverse_it;
|
|
||||||
typedef std::list<Section*>::const_iterator const_it;
|
|
||||||
typedef std::list<Section*>::const_reverse_iterator const_reverse_it;
|
|
||||||
void (* _start_function)(void);
|
|
||||||
bool secure_mode; //Sandbox mode
|
|
||||||
public:
|
|
||||||
Config(CommandLine * cmd):cmdline(cmd),secure_mode(false){}
|
|
||||||
~Config();
|
|
||||||
|
|
||||||
Section_line * AddSection_line(char const * const _name,void (*_initfunction)(Section*));
|
|
||||||
Section_prop * AddSection_prop(char const * const _name,void (*_initfunction)(Section*),bool canchange=false);
|
|
||||||
|
|
||||||
Section* GetSection(int index);
|
|
||||||
Section* GetSection(std::string const&_sectionname) const;
|
|
||||||
Section* GetSectionFromProperty(char const * const prop) const;
|
|
||||||
|
|
||||||
void SetStartUp(void (*_function)(void));
|
|
||||||
void Init();
|
|
||||||
void ShutDown();
|
|
||||||
void StartUp();
|
|
||||||
bool PrintConfig(char const * const configfilename) const;
|
|
||||||
bool ParseConfigFile(char const * const configfilename);
|
|
||||||
void ParseEnv(char ** envp);
|
|
||||||
bool SecureMode() const { return secure_mode; }
|
|
||||||
void SwitchToSecureMode() { secure_mode = true; }//can't be undone
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
515
include/cpu.h
515
include/cpu.h
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2008 The DOSBox Team
|
* Copyright (C) 2002 The DOSBox Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -9,484 +9,91 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Library General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: cpu.h,v 1.56 2009/04/25 16:25:03 harekiet Exp $ */
|
#ifndef __CPU_H
|
||||||
|
#define __CPU_H
|
||||||
|
|
||||||
#ifndef DOSBOX_CPU_H
|
#include <dosbox.h>
|
||||||
#define DOSBOX_CPU_H
|
#include <regs.h>
|
||||||
|
#include <mem.h>
|
||||||
#ifndef DOSBOX_DOSBOX_H
|
|
||||||
#include "dosbox.h"
|
|
||||||
#endif
|
|
||||||
#ifndef DOSBOX_REGS_H
|
|
||||||
#include "regs.h"
|
|
||||||
#endif
|
|
||||||
#ifndef DOSBOX_MEM_H
|
|
||||||
#include "mem.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CPU_AUTODETERMINE_NONE 0x00
|
|
||||||
#define CPU_AUTODETERMINE_CORE 0x01
|
|
||||||
#define CPU_AUTODETERMINE_CYCLES 0x02
|
|
||||||
|
|
||||||
#define CPU_AUTODETERMINE_SHIFT 0x02
|
|
||||||
#define CPU_AUTODETERMINE_MASK 0x03
|
|
||||||
|
|
||||||
#define CPU_CYCLES_LOWER_LIMIT 100
|
|
||||||
|
|
||||||
|
|
||||||
#define CPU_ARCHTYPE_MIXED 0xff
|
|
||||||
#define CPU_ARCHTYPE_386SLOW 0x30
|
|
||||||
#define CPU_ARCHTYPE_386FAST 0x35
|
|
||||||
#define CPU_ARCHTYPE_486OLDSLOW 0x40
|
|
||||||
#define CPU_ARCHTYPE_486NEWSLOW 0x45
|
|
||||||
#define CPU_ARCHTYPE_PENTIUMSLOW 0x50
|
|
||||||
|
|
||||||
/* CPU Cycle Timing */
|
|
||||||
extern Bit32s CPU_Cycles;
|
|
||||||
extern Bit32s CPU_CycleLeft;
|
|
||||||
extern Bit32s CPU_CycleMax;
|
|
||||||
extern Bit32s CPU_OldCycleMax;
|
|
||||||
extern Bit32s CPU_CyclePercUsed;
|
|
||||||
extern Bit32s CPU_CycleLimit;
|
|
||||||
extern Bit64s CPU_IODelayRemoved;
|
|
||||||
extern bool CPU_CycleAutoAdjust;
|
|
||||||
extern bool CPU_SkipCycleAutoAdjust;
|
|
||||||
extern Bitu CPU_AutoDetermineMode;
|
|
||||||
|
|
||||||
extern Bitu CPU_ArchitectureType;
|
|
||||||
|
|
||||||
extern Bitu CPU_PrefetchQueueSize;
|
|
||||||
|
|
||||||
/* Some common Defines */
|
/* Some common Defines */
|
||||||
/* A CPU Handler */
|
/* A CPU Handler */
|
||||||
typedef Bits (CPU_Decoder)(void);
|
typedef Bitu (CPU_Decoder)(Bitu count);
|
||||||
extern CPU_Decoder * cpudecoder;
|
extern CPU_Decoder * cpudecoder;
|
||||||
|
extern Bit32u cpu_cycles;
|
||||||
|
|
||||||
Bits CPU_Core_Normal_Run(void);
|
|
||||||
Bits CPU_Core_Normal_Trap_Run(void);
|
|
||||||
Bits CPU_Core_Simple_Run(void);
|
|
||||||
Bits CPU_Core_Full_Run(void);
|
|
||||||
Bits CPU_Core_Dyn_X86_Run(void);
|
|
||||||
Bits CPU_Core_Dyn_X86_Trap_Run(void);
|
|
||||||
Bits CPU_Core_Dynrec_Run(void);
|
|
||||||
Bits CPU_Core_Dynrec_Trap_Run(void);
|
|
||||||
Bits CPU_Core_Prefetch_Run(void);
|
|
||||||
Bits CPU_Core_Prefetch_Trap_Run(void);
|
|
||||||
|
|
||||||
void CPU_Enable_SkipAutoAdjust(void);
|
|
||||||
void CPU_Disable_SkipAutoAdjust(void);
|
|
||||||
void CPU_Reset_AutoAdjust(void);
|
|
||||||
|
|
||||||
|
extern Bit32u hoever;
|
||||||
|
|
||||||
//CPU Stuff
|
//CPU Stuff
|
||||||
|
void SetCPU16bit();
|
||||||
extern Bit16u parity_lookup[256];
|
void SetSegment_16(Bit32u seg,Bit16u val);
|
||||||
|
|
||||||
bool CPU_LLDT(Bitu selector);
|
|
||||||
bool CPU_LTR(Bitu selector);
|
|
||||||
void CPU_LIDT(Bitu limit,Bitu base);
|
|
||||||
void CPU_LGDT(Bitu limit,Bitu base);
|
|
||||||
|
|
||||||
Bitu CPU_STR(void);
|
|
||||||
Bitu CPU_SLDT(void);
|
|
||||||
Bitu CPU_SIDT_base(void);
|
|
||||||
Bitu CPU_SIDT_limit(void);
|
|
||||||
Bitu CPU_SGDT_base(void);
|
|
||||||
Bitu CPU_SGDT_limit(void);
|
|
||||||
|
|
||||||
void CPU_ARPL(Bitu & dest_sel,Bitu src_sel);
|
|
||||||
void CPU_LAR(Bitu selector,Bitu & ar);
|
|
||||||
void CPU_LSL(Bitu selector,Bitu & limit);
|
|
||||||
|
|
||||||
void CPU_SET_CRX(Bitu cr,Bitu value);
|
|
||||||
bool CPU_WRITE_CRX(Bitu cr,Bitu value);
|
|
||||||
Bitu CPU_GET_CRX(Bitu cr);
|
|
||||||
bool CPU_READ_CRX(Bitu cr,Bit32u & retvalue);
|
|
||||||
|
|
||||||
bool CPU_WRITE_DRX(Bitu dr,Bitu value);
|
|
||||||
bool CPU_READ_DRX(Bitu dr,Bit32u & retvalue);
|
|
||||||
|
|
||||||
bool CPU_WRITE_TRX(Bitu dr,Bitu value);
|
|
||||||
bool CPU_READ_TRX(Bitu dr,Bit32u & retvalue);
|
|
||||||
|
|
||||||
Bitu CPU_SMSW(void);
|
|
||||||
bool CPU_LMSW(Bitu word);
|
|
||||||
|
|
||||||
void CPU_VERR(Bitu selector);
|
|
||||||
void CPU_VERW(Bitu selector);
|
|
||||||
|
|
||||||
void CPU_JMP(bool use32,Bitu selector,Bitu offset,Bitu oldeip);
|
|
||||||
void CPU_CALL(bool use32,Bitu selector,Bitu offset,Bitu oldeip);
|
|
||||||
void CPU_RET(bool use32,Bitu bytes,Bitu oldeip);
|
|
||||||
void CPU_IRET(bool use32,Bitu oldeip);
|
|
||||||
void CPU_HLT(Bitu oldeip);
|
|
||||||
|
|
||||||
bool CPU_POPF(Bitu use32);
|
|
||||||
bool CPU_PUSHF(Bitu use32);
|
|
||||||
bool CPU_CLI(void);
|
|
||||||
bool CPU_STI(void);
|
|
||||||
|
|
||||||
bool CPU_IO_Exception(Bitu port,Bitu size);
|
|
||||||
void CPU_RunException(void);
|
|
||||||
|
|
||||||
void CPU_ENTER(bool use32,Bitu bytes,Bitu level);
|
|
||||||
|
|
||||||
#define CPU_INT_SOFTWARE 0x1
|
|
||||||
#define CPU_INT_EXCEPTION 0x2
|
|
||||||
#define CPU_INT_HAS_ERROR 0x4
|
|
||||||
#define CPU_INT_NOIOPLCHECK 0x8
|
|
||||||
|
|
||||||
void CPU_Interrupt(Bitu num,Bitu type,Bitu oldeip);
|
|
||||||
static INLINE void CPU_HW_Interrupt(Bitu num) {
|
|
||||||
CPU_Interrupt(num,0,reg_eip);
|
|
||||||
}
|
|
||||||
static INLINE void CPU_SW_Interrupt(Bitu num,Bitu oldeip) {
|
|
||||||
CPU_Interrupt(num,CPU_INT_SOFTWARE,oldeip);
|
|
||||||
}
|
|
||||||
static INLINE void CPU_SW_Interrupt_NoIOPLCheck(Bitu num,Bitu oldeip) {
|
|
||||||
CPU_Interrupt(num,CPU_INT_SOFTWARE|CPU_INT_NOIOPLCHECK,oldeip);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CPU_PrepareException(Bitu which,Bitu error);
|
|
||||||
void CPU_Exception(Bitu which,Bitu error=0);
|
|
||||||
|
|
||||||
bool CPU_SetSegGeneral(SegNames seg,Bitu value);
|
|
||||||
bool CPU_PopSeg(SegNames seg,bool use32);
|
|
||||||
|
|
||||||
bool CPU_CPUID(void);
|
|
||||||
Bitu CPU_Pop16(void);
|
|
||||||
Bitu CPU_Pop32(void);
|
|
||||||
void CPU_Push16(Bitu value);
|
|
||||||
void CPU_Push32(Bitu value);
|
|
||||||
|
|
||||||
void CPU_SetFlags(Bitu word,Bitu mask);
|
|
||||||
|
|
||||||
|
|
||||||
#define EXCEPTION_UD 6
|
//Types of Flag changing instructions
|
||||||
#define EXCEPTION_TS 10
|
enum {
|
||||||
#define EXCEPTION_NP 11
|
t_ADDb=0,t_ADDw,t_ADDd,
|
||||||
#define EXCEPTION_SS 12
|
t_ORb,t_ORw,t_ORd,
|
||||||
#define EXCEPTION_GP 13
|
t_ADCb,t_ADCw,t_ADCd,
|
||||||
#define EXCEPTION_PF 14
|
t_SBBb,t_SBBw,t_SBBd,
|
||||||
|
t_ANDb,t_ANDw,t_ANDd,
|
||||||
|
t_SUBb,t_SUBw,t_SUBd,
|
||||||
|
t_XORb,t_XORw,t_XORd,
|
||||||
|
t_CMPb,t_CMPw,t_CMPd,
|
||||||
|
t_INCb,t_INCw,t_INCd,
|
||||||
|
t_DECb,t_DECw,t_DECd,
|
||||||
|
t_TESTb,t_TESTw,t_TESTd,
|
||||||
|
t_SHLb,t_SHLw,t_SHLd,
|
||||||
|
t_SHRb,t_SHRw,t_SHRd,
|
||||||
|
t_SARb,t_SARw,t_SARd,
|
||||||
|
t_ROLb,t_ROLw,t_ROLd,
|
||||||
|
t_RORb,t_RORw,t_RORd,
|
||||||
|
t_RCLb,t_RCLw,t_RCLd,
|
||||||
|
t_RCRb,t_RCRw,t_RCRd,
|
||||||
|
t_NEGb,t_NEGw,t_NEGd,
|
||||||
|
t_CF,t_ZF,
|
||||||
|
|
||||||
#define CR0_PROTECTION 0x00000001
|
t_DSHLw,t_DSHLd,
|
||||||
#define CR0_MONITORPROCESSOR 0x00000002
|
t_DSHRw,t_DSHRd,
|
||||||
#define CR0_FPUEMULATION 0x00000004
|
t_MUL,t_DIV,
|
||||||
#define CR0_TASKSWITCH 0x00000008
|
t_UNKNOWN,
|
||||||
#define CR0_FPUPRESENT 0x00000010
|
t_NOTDONE,
|
||||||
#define CR0_PAGING 0x80000000
|
|
||||||
|
|
||||||
|
|
||||||
// *********************************************************************
|
|
||||||
// Descriptor
|
|
||||||
// *********************************************************************
|
|
||||||
|
|
||||||
#define DESC_INVALID 0x00
|
|
||||||
#define DESC_286_TSS_A 0x01
|
|
||||||
#define DESC_LDT 0x02
|
|
||||||
#define DESC_286_TSS_B 0x03
|
|
||||||
#define DESC_286_CALL_GATE 0x04
|
|
||||||
#define DESC_TASK_GATE 0x05
|
|
||||||
#define DESC_286_INT_GATE 0x06
|
|
||||||
#define DESC_286_TRAP_GATE 0x07
|
|
||||||
|
|
||||||
#define DESC_386_TSS_A 0x09
|
|
||||||
#define DESC_386_TSS_B 0x0b
|
|
||||||
#define DESC_386_CALL_GATE 0x0c
|
|
||||||
#define DESC_386_INT_GATE 0x0e
|
|
||||||
#define DESC_386_TRAP_GATE 0x0f
|
|
||||||
|
|
||||||
/* EU/ED Expand UP/DOWN RO/RW Read Only/Read Write NA/A Accessed */
|
|
||||||
#define DESC_DATA_EU_RO_NA 0x10
|
|
||||||
#define DESC_DATA_EU_RO_A 0x11
|
|
||||||
#define DESC_DATA_EU_RW_NA 0x12
|
|
||||||
#define DESC_DATA_EU_RW_A 0x13
|
|
||||||
#define DESC_DATA_ED_RO_NA 0x14
|
|
||||||
#define DESC_DATA_ED_RO_A 0x15
|
|
||||||
#define DESC_DATA_ED_RW_NA 0x16
|
|
||||||
#define DESC_DATA_ED_RW_A 0x17
|
|
||||||
|
|
||||||
/* N/R Readable NC/C Confirming A/NA Accessed */
|
|
||||||
#define DESC_CODE_N_NC_A 0x18
|
|
||||||
#define DESC_CODE_N_NC_NA 0x19
|
|
||||||
#define DESC_CODE_R_NC_A 0x1a
|
|
||||||
#define DESC_CODE_R_NC_NA 0x1b
|
|
||||||
#define DESC_CODE_N_C_A 0x1c
|
|
||||||
#define DESC_CODE_N_C_NA 0x1d
|
|
||||||
#define DESC_CODE_R_C_A 0x1e
|
|
||||||
#define DESC_CODE_R_C_NA 0x1f
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma pack (1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct S_Descriptor {
|
|
||||||
#ifdef WORDS_BIGENDIAN
|
|
||||||
Bit32u base_0_15 :16;
|
|
||||||
Bit32u limit_0_15 :16;
|
|
||||||
Bit32u base_24_31 :8;
|
|
||||||
Bit32u g :1;
|
|
||||||
Bit32u big :1;
|
|
||||||
Bit32u r :1;
|
|
||||||
Bit32u avl :1;
|
|
||||||
Bit32u limit_16_19 :4;
|
|
||||||
Bit32u p :1;
|
|
||||||
Bit32u dpl :2;
|
|
||||||
Bit32u type :5;
|
|
||||||
Bit32u base_16_23 :8;
|
|
||||||
#else
|
|
||||||
Bit32u limit_0_15 :16;
|
|
||||||
Bit32u base_0_15 :16;
|
|
||||||
Bit32u base_16_23 :8;
|
|
||||||
Bit32u type :5;
|
|
||||||
Bit32u dpl :2;
|
|
||||||
Bit32u p :1;
|
|
||||||
Bit32u limit_16_19 :4;
|
|
||||||
Bit32u avl :1;
|
|
||||||
Bit32u r :1;
|
|
||||||
Bit32u big :1;
|
|
||||||
Bit32u g :1;
|
|
||||||
Bit32u base_24_31 :8;
|
|
||||||
#endif
|
|
||||||
}GCC_ATTRIBUTE(packed);
|
|
||||||
|
|
||||||
struct G_Descriptor {
|
|
||||||
#ifdef WORDS_BIGENDIAN
|
|
||||||
Bit32u selector: 16;
|
|
||||||
Bit32u offset_0_15 :16;
|
|
||||||
Bit32u offset_16_31 :16;
|
|
||||||
Bit32u p :1;
|
|
||||||
Bit32u dpl :2;
|
|
||||||
Bit32u type :5;
|
|
||||||
Bit32u reserved :3;
|
|
||||||
Bit32u paramcount :5;
|
|
||||||
#else
|
|
||||||
Bit32u offset_0_15 :16;
|
|
||||||
Bit32u selector :16;
|
|
||||||
Bit32u paramcount :5;
|
|
||||||
Bit32u reserved :3;
|
|
||||||
Bit32u type :5;
|
|
||||||
Bit32u dpl :2;
|
|
||||||
Bit32u p :1;
|
|
||||||
Bit32u offset_16_31 :16;
|
|
||||||
#endif
|
|
||||||
} GCC_ATTRIBUTE(packed);
|
|
||||||
|
|
||||||
struct TSS_16 {
|
|
||||||
Bit16u back; /* Back link to other task */
|
|
||||||
Bit16u sp0; /* The CK stack pointer */
|
|
||||||
Bit16u ss0; /* The CK stack selector */
|
|
||||||
Bit16u sp1; /* The parent KL stack pointer */
|
|
||||||
Bit16u ss1; /* The parent KL stack selector */
|
|
||||||
Bit16u sp2; /* Unused */
|
|
||||||
Bit16u ss2; /* Unused */
|
|
||||||
Bit16u ip; /* The instruction pointer */
|
|
||||||
Bit16u flags; /* The flags */
|
|
||||||
Bit16u ax, cx, dx, bx; /* The general purpose registers */
|
|
||||||
Bit16u sp, bp, si, di; /* The special purpose registers */
|
|
||||||
Bit16u es; /* The extra selector */
|
|
||||||
Bit16u cs; /* The code selector */
|
|
||||||
Bit16u ss; /* The application stack selector */
|
|
||||||
Bit16u ds; /* The data selector */
|
|
||||||
Bit16u ldt; /* The local descriptor table */
|
|
||||||
} GCC_ATTRIBUTE(packed);
|
|
||||||
|
|
||||||
struct TSS_32 {
|
|
||||||
Bit32u back; /* Back link to other task */
|
|
||||||
Bit32u esp0; /* The CK stack pointer */
|
|
||||||
Bit32u ss0; /* The CK stack selector */
|
|
||||||
Bit32u esp1; /* The parent KL stack pointer */
|
|
||||||
Bit32u ss1; /* The parent KL stack selector */
|
|
||||||
Bit32u esp2; /* Unused */
|
|
||||||
Bit32u ss2; /* Unused */
|
|
||||||
Bit32u cr3; /* The page directory pointer */
|
|
||||||
Bit32u eip; /* The instruction pointer */
|
|
||||||
Bit32u eflags; /* The flags */
|
|
||||||
Bit32u eax, ecx, edx, ebx; /* The general purpose registers */
|
|
||||||
Bit32u esp, ebp, esi, edi; /* The special purpose registers */
|
|
||||||
Bit32u es; /* The extra selector */
|
|
||||||
Bit32u cs; /* The code selector */
|
|
||||||
Bit32u ss; /* The application stack selector */
|
|
||||||
Bit32u ds; /* The data selector */
|
|
||||||
Bit32u fs; /* And another extra selector */
|
|
||||||
Bit32u gs; /* ... and another one */
|
|
||||||
Bit32u ldt; /* The local descriptor table */
|
|
||||||
} GCC_ATTRIBUTE(packed);
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma pack()
|
|
||||||
#endif
|
|
||||||
class Descriptor
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Descriptor() { saved.fill[0]=saved.fill[1]=0; }
|
|
||||||
|
|
||||||
void Load(PhysPt address);
|
|
||||||
void Save(PhysPt address);
|
|
||||||
|
|
||||||
PhysPt GetBase (void) {
|
|
||||||
return (saved.seg.base_24_31<<24) | (saved.seg.base_16_23<<16) | saved.seg.base_0_15;
|
|
||||||
}
|
|
||||||
Bitu GetLimit (void) {
|
|
||||||
Bitu limit = (saved.seg.limit_16_19<<16) | saved.seg.limit_0_15;
|
|
||||||
if (saved.seg.g) return (limit<<12) | 0xFFF;
|
|
||||||
return limit;
|
|
||||||
}
|
|
||||||
Bitu GetOffset(void) {
|
|
||||||
return (saved.gate.offset_16_31 << 16) | saved.gate.offset_0_15;
|
|
||||||
}
|
|
||||||
Bitu GetSelector(void) {
|
|
||||||
return saved.gate.selector;
|
|
||||||
}
|
|
||||||
Bitu Type(void) {
|
|
||||||
return saved.seg.type;
|
|
||||||
}
|
|
||||||
Bitu Conforming(void) {
|
|
||||||
return saved.seg.type & 8;
|
|
||||||
}
|
|
||||||
Bitu DPL(void) {
|
|
||||||
return saved.seg.dpl;
|
|
||||||
}
|
|
||||||
Bitu Big(void) {
|
|
||||||
return saved.seg.big;
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
union {
|
|
||||||
S_Descriptor seg;
|
|
||||||
G_Descriptor gate;
|
|
||||||
Bit32u fill[2];
|
|
||||||
} saved;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class DescriptorTable {
|
enum { rep_NONE,rep_Z,rep_NZ };
|
||||||
public:
|
|
||||||
PhysPt GetBase (void) { return table_base; }
|
|
||||||
Bitu GetLimit (void) { return table_limit; }
|
|
||||||
void SetBase (PhysPt _base) { table_base = _base; }
|
|
||||||
void SetLimit (Bitu _limit) { table_limit= _limit; }
|
|
||||||
|
|
||||||
bool GetDescriptor (Bitu selector, Descriptor& desc) {
|
|
||||||
selector&=~7;
|
|
||||||
if (selector>=table_limit) return false;
|
|
||||||
desc.Load(table_base+(selector));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
protected:
|
|
||||||
PhysPt table_base;
|
|
||||||
Bitu table_limit;
|
|
||||||
};
|
|
||||||
|
|
||||||
class GDTDescriptorTable : public DescriptorTable {
|
|
||||||
public:
|
|
||||||
bool GetDescriptor(Bitu selector, Descriptor& desc) {
|
|
||||||
Bitu address=selector & ~7;
|
|
||||||
if (selector & 4) {
|
|
||||||
if (address>=ldt_limit) return false;
|
|
||||||
desc.Load(ldt_base+address);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
if (address>=table_limit) return false;
|
|
||||||
desc.Load(table_base+address);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bool SetDescriptor(Bitu selector, Descriptor& desc) {
|
|
||||||
Bitu address=selector & ~7;
|
|
||||||
if (selector & 4) {
|
|
||||||
if (address>=ldt_limit) return false;
|
|
||||||
desc.Save(ldt_base+address);
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
if (address>=table_limit) return false;
|
|
||||||
desc.Save(table_base+address);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Bitu SLDT(void) {
|
|
||||||
return ldt_value;
|
|
||||||
}
|
|
||||||
bool LLDT(Bitu value) {
|
|
||||||
if ((value&0xfffc)==0) {
|
|
||||||
ldt_value=0;
|
|
||||||
ldt_base=0;
|
|
||||||
ldt_limit=0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
Descriptor desc;
|
|
||||||
if (!GetDescriptor(value,desc)) return !CPU_PrepareException(EXCEPTION_GP,value);
|
|
||||||
if (desc.Type()!=DESC_LDT) return !CPU_PrepareException(EXCEPTION_GP,value);
|
|
||||||
if (!desc.saved.seg.p) return !CPU_PrepareException(EXCEPTION_NP,value);
|
|
||||||
ldt_base=desc.GetBase();
|
|
||||||
ldt_limit=desc.GetLimit();
|
|
||||||
ldt_value=value;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
PhysPt ldt_base;
|
|
||||||
Bitu ldt_limit;
|
|
||||||
Bitu ldt_value;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TSS_Descriptor : public Descriptor {
|
|
||||||
public:
|
|
||||||
Bitu IsBusy(void) {
|
|
||||||
return saved.seg.type & 2;
|
|
||||||
}
|
|
||||||
Bitu Is386(void) {
|
|
||||||
return saved.seg.type & 8;
|
|
||||||
}
|
|
||||||
void SetBusy(bool busy) {
|
|
||||||
if (busy) saved.seg.type|=2;
|
|
||||||
else saved.seg.type&=~2;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
struct CPUBlock {
|
void Interrupt(Bit8u num);
|
||||||
Bitu cpl; /* Current Privilege */
|
|
||||||
Bitu mpl;
|
|
||||||
Bitu cr0;
|
|
||||||
bool pmode; /* Is Protected mode enabled */
|
|
||||||
GDTDescriptorTable gdt;
|
|
||||||
DescriptorTable idt;
|
|
||||||
struct {
|
|
||||||
Bitu mask,notmask;
|
|
||||||
bool big;
|
|
||||||
} stack;
|
|
||||||
struct {
|
|
||||||
bool big;
|
|
||||||
} code;
|
|
||||||
struct {
|
|
||||||
Bitu cs,eip;
|
|
||||||
CPU_Decoder * old_decoder;
|
|
||||||
} hlt;
|
|
||||||
struct {
|
|
||||||
Bitu which,error;
|
|
||||||
} exception;
|
|
||||||
Bits direction;
|
|
||||||
bool trap_skip;
|
|
||||||
Bit32u drx[8];
|
|
||||||
Bit32u trx[8];
|
|
||||||
};
|
|
||||||
|
|
||||||
extern CPUBlock cpu;
|
//Flag Handling
|
||||||
|
bool get_CF(void);
|
||||||
|
bool get_AF(void);
|
||||||
|
bool get_ZF(void);
|
||||||
|
bool get_SF(void);
|
||||||
|
bool get_OF(void);
|
||||||
|
bool get_PF(void);
|
||||||
|
|
||||||
static INLINE void CPU_SetFlagsd(Bitu word) {
|
Bit8u get_Flags8(void);
|
||||||
Bitu mask=cpu.cpl ? FMASK_NORMAL : FMASK_ALL;
|
|
||||||
CPU_SetFlags(word,mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void CPU_SetFlagsw(Bitu word) {
|
|
||||||
Bitu mask=(cpu.cpl ? FMASK_NORMAL : FMASK_ALL) & 0xffff;
|
|
||||||
CPU_SetFlags(word,mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define LoadCF flags.cf=get_CF();
|
||||||
|
#define LoadZF flags.zf=get_ZF();
|
||||||
|
#define LoadSF flags.sf=get_SF();
|
||||||
|
#define LoadOF flags.of=get_OF();
|
||||||
|
//The opcode handlers
|
||||||
|
|
||||||
|
|
||||||
|
void FPU_ESC0_Normal(Bitu rm);
|
||||||
|
void FPU_ESC0_EA(Bitu func,PhysOff ea);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2009 The DOSBox Team
|
* Copyright (C) 2002 The DOSBox Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -9,43 +9,32 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Library General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: cross.h,v 1.21 2009/03/14 18:02:34 qbix79 Exp $ */
|
#ifndef _CROSS_H
|
||||||
|
#define _CROSS_H
|
||||||
#ifndef DOSBOX_CROSS_H
|
|
||||||
#define DOSBOX_CROSS_H
|
|
||||||
|
|
||||||
#ifndef DOSBOX_DOSBOX_H
|
|
||||||
#include "dosbox.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#if defined (_MSC_VER) /* MS Visual C++ */
|
#if defined (_MSC_VER) /* MS Visual C++ */
|
||||||
#include <direct.h>
|
#include <direct.h>
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#define LONGTYPE(a) a##i64
|
#else /* LINUX */
|
||||||
#define snprintf _snprintf
|
|
||||||
#define vsnprintf _vsnprintf
|
|
||||||
#else /* LINUX / GCC */
|
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#define LONGTYPE(a) a##LL
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define CROSS_LEN 512 /* Maximum filename size */
|
#define CROSS_LEN 512 /* Maximum filename size */
|
||||||
|
|
||||||
|
|
||||||
#if defined (WIN32) || defined (OS2) /* Win 32 & OS/2*/
|
#if defined (_MSC_VER) /* MS Visual C++ */
|
||||||
#define CROSS_FILENAME(blah)
|
#define CROSS_FILENAME(blah)
|
||||||
#define CROSS_FILESPLIT '\\'
|
#define CROSS_FILESPLIT '\\'
|
||||||
#define F_OK 0
|
#define F_OK 0
|
||||||
@ -57,52 +46,9 @@
|
|||||||
#define CROSS_NONE 0
|
#define CROSS_NONE 0
|
||||||
#define CROSS_FILE 1
|
#define CROSS_FILE 1
|
||||||
#define CROSS_DIR 2
|
#define CROSS_DIR 2
|
||||||
#if defined (WIN32)
|
|
||||||
#define ftruncate(blah,blah2) chsize(blah,blah2)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//Solaris maybe others
|
|
||||||
#if defined (DB_HAVE_NO_POWF)
|
|
||||||
#include <math.h>
|
|
||||||
static inline float powf (float x, float y) { return (float) pow (x,y); }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class Cross {
|
|
||||||
public:
|
|
||||||
static void GetPlatformConfigDir(std::string& in);
|
|
||||||
static void GetPlatformConfigName(std::string& in);
|
|
||||||
static void CreatePlatformConfigDir(std::string& in);
|
|
||||||
static void ResolveHomedir(std::string & temp_line);
|
|
||||||
static void CreateDir(std::string const& temp);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#if defined (WIN32)
|
extern const char * dosbox_datadir;
|
||||||
|
|
||||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
typedef struct dir_struct {
|
|
||||||
HANDLE handle;
|
|
||||||
char base_path[MAX_PATH+4];
|
|
||||||
WIN32_FIND_DATA search_data;
|
|
||||||
} dir_information;
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
//#include <sys/types.h> //Included above
|
|
||||||
#include <dirent.h>
|
|
||||||
|
|
||||||
typedef struct dir_struct {
|
|
||||||
DIR* dir;
|
|
||||||
char base_path[CROSS_LEN];
|
|
||||||
} dir_information;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
dir_information* open_directory(const char* dirname);
|
|
||||||
bool read_directory_first(dir_information* dirp, char* entry_name, bool& is_directory);
|
|
||||||
bool read_directory_next(dir_information* dirp, char* entry_name, bool& is_directory);
|
|
||||||
void close_directory(dir_information* dirp);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2007 The DOSBox Team
|
* Copyright (C) 2002 The DOSBox Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -9,27 +9,16 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Library General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void DEBUG_SetupConsole(void);
|
|
||||||
void DEBUG_DrawScreen(void);
|
void DEBUG_DrawScreen(void);
|
||||||
bool DEBUG_Breakpoint(void);
|
bool DEBUG_BreakPoint(void);
|
||||||
bool DEBUG_IntBreakpoint(Bit8u intNum);
|
void DEBUG_Enable(void);
|
||||||
void DEBUG_Enable(bool pressed);
|
|
||||||
void DEBUG_CheckExecuteBreakpoint(Bit16u seg, Bit32u off);
|
|
||||||
bool DEBUG_ExitLoop(void);
|
|
||||||
void DEBUG_RefreshPage(char scroll);
|
|
||||||
Bitu DEBUG_EnableDebugger(void);
|
|
||||||
|
|
||||||
extern Bitu cycle_count;
|
extern Bitu cycle_count;
|
||||||
extern Bitu debugCallback;
|
|
||||||
|
|
||||||
#ifdef C_HEAVY_DEBUG
|
|
||||||
bool DEBUG_HeavyIsBreakpoint(void);
|
|
||||||
void DEBUG_HeavyWriteLogInstruction(void);
|
|
||||||
#endif
|
|
||||||
|
105
include/dma.h
105
include/dma.h
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2008 The DOSBox Team
|
* Copyright (C) 2002 The DOSBox Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -9,109 +9,16 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Library General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: dma.h,v 1.18 2008/09/13 20:04:28 c2woody Exp $ */
|
void DMA_8_Read(Bit32u channel,Bit8u * buffer,Bit16u count);
|
||||||
|
void DMA_8_Write(Bit32u dmachan,Bit8u * buffer,Bit16u count);
|
||||||
|
|
||||||
#ifndef DOSBOX_DMA_H
|
void DMA_16_Read(Bit32u channel,Bit8u * buffer,Bit16u count);
|
||||||
#define DOSBOX_DMA_H
|
void DMA_16_Write(Bit32u dmachan,Bit8u * buffer,Bit16u count);
|
||||||
|
|
||||||
enum DMAEvent {
|
|
||||||
DMA_REACHED_TC,
|
|
||||||
DMA_MASKED,
|
|
||||||
DMA_UNMASKED,
|
|
||||||
DMA_TRANSFEREND
|
|
||||||
};
|
|
||||||
|
|
||||||
class DmaChannel;
|
|
||||||
typedef void (* DMA_CallBack)(DmaChannel * chan,DMAEvent event);
|
|
||||||
|
|
||||||
class DmaChannel {
|
|
||||||
public:
|
|
||||||
Bit32u pagebase;
|
|
||||||
Bit16u baseaddr;
|
|
||||||
Bit16u curraddr;
|
|
||||||
Bit16u basecnt;
|
|
||||||
Bit16u currcnt;
|
|
||||||
Bit8u channum;
|
|
||||||
Bit8u pagenum;
|
|
||||||
Bit8u DMA16;
|
|
||||||
bool increment;
|
|
||||||
bool autoinit;
|
|
||||||
Bit8u trantype;
|
|
||||||
bool masked;
|
|
||||||
bool tcount;
|
|
||||||
bool request;
|
|
||||||
DMA_CallBack callback;
|
|
||||||
|
|
||||||
DmaChannel(Bit8u num, bool dma16);
|
|
||||||
void DoCallBack(DMAEvent event) {
|
|
||||||
if (callback) (*callback)(this,event);
|
|
||||||
}
|
|
||||||
void SetMask(bool _mask) {
|
|
||||||
masked=_mask;
|
|
||||||
DoCallBack(masked ? DMA_MASKED : DMA_UNMASKED);
|
|
||||||
}
|
|
||||||
void Register_Callback(DMA_CallBack _cb) {
|
|
||||||
callback = _cb;
|
|
||||||
SetMask(masked);
|
|
||||||
if (callback) Raise_Request();
|
|
||||||
else Clear_Request();
|
|
||||||
}
|
|
||||||
void ReachedTC(void) {
|
|
||||||
tcount=true;
|
|
||||||
DoCallBack(DMA_REACHED_TC);
|
|
||||||
}
|
|
||||||
void SetPage(Bit8u val) {
|
|
||||||
pagenum=val;
|
|
||||||
pagebase=(pagenum >> DMA16) << (16+DMA16);
|
|
||||||
}
|
|
||||||
void Raise_Request(void) {
|
|
||||||
request=true;
|
|
||||||
}
|
|
||||||
void Clear_Request(void) {
|
|
||||||
request=false;
|
|
||||||
}
|
|
||||||
Bitu Read(Bitu size, Bit8u * buffer);
|
|
||||||
Bitu Write(Bitu size, Bit8u * buffer);
|
|
||||||
};
|
|
||||||
|
|
||||||
class DmaController {
|
|
||||||
private:
|
|
||||||
Bit8u ctrlnum;
|
|
||||||
bool flipflop;
|
|
||||||
DmaChannel *DmaChannels[4];
|
|
||||||
public:
|
|
||||||
IO_ReadHandleObject DMA_ReadHandler[0x11];
|
|
||||||
IO_WriteHandleObject DMA_WriteHandler[0x11];
|
|
||||||
DmaController(Bit8u num) {
|
|
||||||
flipflop = false;
|
|
||||||
ctrlnum = num; /* first or second DMA controller */
|
|
||||||
for(Bit8u i=0;i<4;i++) {
|
|
||||||
DmaChannels[i] = new DmaChannel(i+ctrlnum*4,ctrlnum==1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
~DmaController(void) {
|
|
||||||
for(Bit8u i=0;i<4;i++) {
|
|
||||||
delete DmaChannels[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DmaChannel * GetChannel(Bit8u chan) {
|
|
||||||
if (chan<4) return DmaChannels[chan];
|
|
||||||
else return NULL;
|
|
||||||
}
|
|
||||||
void WriteControllerReg(Bitu reg,Bitu val,Bitu len);
|
|
||||||
Bitu ReadControllerReg(Bitu reg,Bitu len);
|
|
||||||
};
|
|
||||||
|
|
||||||
DmaChannel * GetDMAChannel(Bit8u chan);
|
|
||||||
|
|
||||||
void CloseSecondDMAController(void);
|
|
||||||
bool SecondDMAControllerAvailable(void);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2008 The DOSBox Team
|
* Copyright (C) 2002 The DOSBox Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -9,35 +9,94 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Library General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: dos_inc.h,v 1.77 2009/04/25 16:25:03 harekiet Exp $ */
|
#ifndef DOS_H_
|
||||||
|
#define DOS_H_
|
||||||
|
|
||||||
#ifndef DOSBOX_DOS_INC_H
|
#include <dos_system.h>
|
||||||
#define DOSBOX_DOS_INC_H
|
#include <mem.h>
|
||||||
|
|
||||||
#ifndef DOSBOX_DOS_SYSTEM_H
|
|
||||||
#include "dos_system.h"
|
|
||||||
#endif
|
|
||||||
#ifndef DOSBOX_MEM_H
|
|
||||||
#include "mem.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
#endif
|
|
||||||
struct CommandTail{
|
struct CommandTail{
|
||||||
Bit8u count; /* number of bytes returned */
|
Bit8u count; /* number of bytes returned */
|
||||||
char buffer[127]; /* the buffer itself */
|
char buffer[127]; /* the buffer itself */
|
||||||
} GCC_ATTRIBUTE(packed);
|
};
|
||||||
#ifdef _MSC_VER
|
|
||||||
|
struct PSP {
|
||||||
|
Bit8u exit[2]; /* CP/M-like exit poimt */
|
||||||
|
Bit16u mem_size; /* memory size in paragraphs */
|
||||||
|
Bit8u fill_1; /* single char fill */
|
||||||
|
|
||||||
|
/* CPM Stuff dunno what this is*/
|
||||||
|
//TODO Add some checks for people using this i think
|
||||||
|
Bit8u far_call; /* far call opcode */
|
||||||
|
RealPt cpm_entry; /* CPM Service Request address*/
|
||||||
|
RealPt int_22; /* Terminate Address */
|
||||||
|
RealPt int_23; /* Break Address */
|
||||||
|
RealPt int_24; /* Critical Error Address */
|
||||||
|
Bit16u psp_parent; /* Parent PSP Segment */
|
||||||
|
Bit8u files[20]; /* File Table - 0xff is unused */
|
||||||
|
Bit16u environment; /* Segment of evironment table */
|
||||||
|
RealPt stack; /* SS:SP Save point for int 0x21 calls */
|
||||||
|
Bit16u max_files; /* Maximum open files */
|
||||||
|
RealPt file_table; /* Pointer to File Table PSP:0x18 */
|
||||||
|
RealPt prev_psp; /* Pointer to previous PSP */
|
||||||
|
RealPt dta; /* Pointer to current Process DTA */
|
||||||
|
Bit8u fill_2[16]; /* Lot's of unused stuff i can't care aboue */
|
||||||
|
Bit8u service[3]; /* INT 0x21 Service call int 0x21;retf; */
|
||||||
|
Bit8u fill_3[45]; /* This has some blocks with FCB info */
|
||||||
|
|
||||||
|
CommandTail cmdtail;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ParamBlock {
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
Bit16u loadseg;
|
||||||
|
Bit16u relocation;
|
||||||
|
} overlay;
|
||||||
|
struct {
|
||||||
|
Bit16u envseg;
|
||||||
|
RealPt cmdtail;
|
||||||
|
RealPt fcb1;
|
||||||
|
RealPt fcb2;
|
||||||
|
RealPt initsssp;
|
||||||
|
RealPt initcsip;
|
||||||
|
} exec;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MCB {
|
||||||
|
Bit8u type;
|
||||||
|
Bit16u psp_segment;
|
||||||
|
Bit16u size;
|
||||||
|
Bit8u unused[3];
|
||||||
|
Bit8u filename[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FCB {
|
||||||
|
Bit8u drive; //0 is current drive. when opened 0 is replaced by drivenumber
|
||||||
|
Bit8u filename[8]; //spacepadded to fit
|
||||||
|
Bit8u ext[3]; //spacepadded to fit
|
||||||
|
Bit16u current_block; // set to 0 by open
|
||||||
|
Bit16u record_size; // used by reads Set to 80h by OPEN function
|
||||||
|
Bit32u filesize; //in bytes In this field, the first word is the low-order part of the size
|
||||||
|
Bit16u date;
|
||||||
|
Bit16u time;
|
||||||
|
Bit8u reserved[8];
|
||||||
|
Bit8u current_relative_record_number; //open doesn't set this
|
||||||
|
Bit32u rel_record; //open does not handle this
|
||||||
|
};
|
||||||
|
|
||||||
#pragma pack()
|
#pragma pack()
|
||||||
#endif
|
|
||||||
|
|
||||||
struct DOS_Date {
|
struct DOS_Date {
|
||||||
Bit16u year;
|
Bit16u year;
|
||||||
@ -45,116 +104,88 @@ struct DOS_Date {
|
|||||||
Bit8u day;
|
Bit8u day;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct DOS_Version {
|
struct DOS_Version {
|
||||||
Bit8u major,minor,revision;
|
Bit8u major,minor,revision;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct DOS_Block {
|
||||||
|
DOS_Date date;
|
||||||
|
DOS_Version version;
|
||||||
|
Bit16u firstMCB;
|
||||||
|
Bit16u errorcode;
|
||||||
|
Bit16u psp;
|
||||||
|
Bit16u env;
|
||||||
|
RealPt cpmentry;
|
||||||
|
RealPt dta;
|
||||||
|
Bit8u return_code,return_mode;
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
bool verify;
|
||||||
#pragma pack (1)
|
bool breakcheck;
|
||||||
#endif
|
struct {
|
||||||
union bootSector {
|
RealPt indosflag;
|
||||||
struct entries {
|
} tables;
|
||||||
Bit8u jump[3];
|
|
||||||
Bit8u oem_name[8];
|
|
||||||
Bit16u bytesect;
|
|
||||||
Bit8u sectclust;
|
|
||||||
Bit16u reserve_sect;
|
|
||||||
Bit8u misc[496];
|
|
||||||
} bootdata;
|
|
||||||
Bit8u rawdata[512];
|
|
||||||
} GCC_ATTRIBUTE(packed);
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma pack ()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
enum { MCB_FREE=0x0000,MCB_DOS=0x0008 };
|
enum { MCB_FREE=0x0000,MCB_DOS=0x0008 };
|
||||||
enum { RETURN_EXIT=0,RETURN_CTRLC=1,RETURN_ABORT=2,RETURN_TSR=3};
|
enum { RETURN_EXIT=0,RETURN_CTRLC=1,RETURN_ABORT=2,RETURN_TSR=3};
|
||||||
|
|
||||||
#define DOS_FILES 127
|
#define DOS_FILES 50
|
||||||
#define DOS_DRIVES 26
|
#define DOS_DRIVES 26
|
||||||
#define DOS_DEVICES 10
|
|
||||||
|
|
||||||
|
|
||||||
// dos swappable area is 0x320 bytes beyond the sysvars table
|
|
||||||
// device driver chain is inside sysvars
|
|
||||||
#define DOS_INFOBLOCK_SEG 0x80 // sysvars (list of lists)
|
|
||||||
#define DOS_CONDRV_SEG 0xa0
|
|
||||||
#define DOS_CONSTRING_SEG 0xa8
|
|
||||||
#define DOS_SDA_SEG 0xb2 // dos swappable area
|
|
||||||
#define DOS_SDA_OFS 0
|
|
||||||
#define DOS_CDS_SEG 0x108
|
|
||||||
#define DOS_FIRST_SHELL 0x118
|
|
||||||
#define DOS_MEM_START 0x158 //First Segment that DOS can use
|
|
||||||
|
|
||||||
#define DOS_PRIVATE_SEGMENT 0xc800
|
|
||||||
#define DOS_PRIVATE_SEGMENT_END 0xd000
|
|
||||||
|
|
||||||
/* internal Dos Tables */
|
/* internal Dos Tables */
|
||||||
|
extern DOS_Block dos;
|
||||||
extern DOS_File * Files[DOS_FILES];
|
extern DOS_File * Files[DOS_FILES];
|
||||||
extern DOS_Drive * Drives[DOS_DRIVES];
|
extern DOS_Drive * Drives[DOS_DRIVES];
|
||||||
extern DOS_Device * Devices[DOS_DEVICES];
|
|
||||||
|
|
||||||
extern Bit8u dos_copybuf[0x10000];
|
|
||||||
|
|
||||||
|
|
||||||
void DOS_SetError(Bit16u code);
|
void DOS_SetError(Bit16u code);
|
||||||
|
|
||||||
/* File Handling Routines */
|
/* File Handling Routines */
|
||||||
|
|
||||||
enum { STDIN=0,STDOUT=1,STDERR=2,STDAUX=3,STDPRN=4};
|
enum { STDIN=0,STDOUT=1,STDERR=2,STDAUX=3,STDNUL=4,STDPRN=5};
|
||||||
enum { HAND_NONE=0,HAND_FILE,HAND_DEVICE};
|
enum { HAND_NONE=0,HAND_FILE,HAND_DEVICE};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Routines for File Class */
|
/* Routines for File Class */
|
||||||
void DOS_SetupFiles (void);
|
void DOS_SetupFiles (void);
|
||||||
|
|
||||||
bool DOS_ReadFile(Bit16u handle,Bit8u * data,Bit16u * amount);
|
bool DOS_ReadFile(Bit16u handle,Bit8u * data,Bit16u * amount);
|
||||||
bool DOS_WriteFile(Bit16u handle,Bit8u * data,Bit16u * amount);
|
bool DOS_WriteFile(Bit16u handle,Bit8u * data,Bit16u * amount);
|
||||||
bool DOS_SeekFile(Bit16u handle,Bit32u * pos,Bit32u type);
|
bool DOS_SeekFile(Bit16u handle,Bit32u * pos,Bit32u type);
|
||||||
bool DOS_CloseFile(Bit16u handle);
|
bool DOS_CloseFile(Bit16u handle);
|
||||||
bool DOS_FlushFile(Bit16u handle);
|
|
||||||
bool DOS_DuplicateEntry(Bit16u entry,Bit16u * newentry);
|
bool DOS_DuplicateEntry(Bit16u entry,Bit16u * newentry);
|
||||||
bool DOS_ForceDuplicateEntry(Bit16u entry,Bit16u newentry);
|
|
||||||
bool DOS_GetFileDate(Bit16u entry, Bit16u* otime, Bit16u* odate);
|
|
||||||
|
|
||||||
/* Routines for Drive Class */
|
/* Routines for Drive Class */
|
||||||
bool DOS_OpenFile(char const * name,Bit8u flags,Bit16u * entry);
|
bool DOS_OpenFile(char * name,Bit8u flags,Bit16u * entry);
|
||||||
bool DOS_OpenFileExtended(char const * name, Bit16u flags, Bit16u createAttr, Bit16u action, Bit16u *entry, Bit16u* status);
|
bool DOS_CreateFile(char * name,Bit16u attribute,Bit16u * entry);
|
||||||
bool DOS_CreateFile(char const * name,Bit16u attribute,Bit16u * entry);
|
bool DOS_UnlinkFile(char * name);
|
||||||
bool DOS_UnlinkFile(char const * const name);
|
bool DOS_FindFirst(char *search,Bit16u attr);
|
||||||
bool DOS_FindFirst(char *search,Bit16u attr,bool fcb_findfirst=false);
|
|
||||||
bool DOS_FindNext(void);
|
bool DOS_FindNext(void);
|
||||||
bool DOS_Canonicalize(char const * const name,char * const big);
|
bool DOS_Canonicalize(char * small,Bit8u * big);
|
||||||
bool DOS_CreateTempFile(char * const name,Bit16u * entry);
|
bool DOS_CreateTempFile(char * name,Bit16u * entry);
|
||||||
bool DOS_FileExists(char const * const name);
|
bool DOS_FileExists(char * name);
|
||||||
|
|
||||||
/* Helper Functions */
|
|
||||||
bool DOS_MakeName(char const * const name,char * const fullname,Bit8u * drive);
|
|
||||||
/* Drive Handing Routines */
|
/* Drive Handing Routines */
|
||||||
Bit8u DOS_GetDefaultDrive(void);
|
Bit8u DOS_GetDefaultDrive(void);
|
||||||
void DOS_SetDefaultDrive(Bit8u drive);
|
void DOS_SetDefaultDrive(Bit8u drive);
|
||||||
bool DOS_SetDrive(Bit8u drive);
|
bool DOS_SetDrive(Bit8u drive);
|
||||||
bool DOS_GetCurrentDir(Bit8u drive,char * const buffer);
|
bool DOS_GetCurrentDir(Bit8u drive,Bit8u * buffer);
|
||||||
bool DOS_ChangeDir(char const * const dir);
|
bool DOS_ChangeDir(char * dir);
|
||||||
bool DOS_MakeDir(char const * const dir);
|
bool DOS_MakeDir(char * dir);
|
||||||
bool DOS_RemoveDir(char const * const dir);
|
bool DOS_RemoveDir(char * dir);
|
||||||
bool DOS_Rename(char const * const oldname,char const * const newname);
|
bool DOS_Rename(char * oldname,char * newname);
|
||||||
bool DOS_GetFreeDiskSpace(Bit8u drive,Bit16u * bytes,Bit8u * sectors,Bit16u * clusters,Bit16u * free);
|
bool DOS_GetFreeDiskSpace(Bit8u drive,Bit16u * bytes,Bit16u * sectors,Bit16u * clusters,Bit16u * free);
|
||||||
bool DOS_GetFileAttr(char const * const name,Bit16u * attr);
|
bool DOS_GetFileAttr(char * name,Bit16u * attr);
|
||||||
bool DOS_SetFileAttr(char const * const name,Bit16u attr);
|
|
||||||
|
|
||||||
/* IOCTL Stuff */
|
/* IOCTL Stuff */
|
||||||
bool DOS_IOCTL(void);
|
bool DOS_IOCTL(Bit8u call,Bit16u entry);
|
||||||
bool DOS_GetSTDINStatus();
|
bool DOS_GetSTDINStatus();
|
||||||
Bit8u DOS_FindDevice(char const * name);
|
Bit8u DOS_FindDevice(char * name);
|
||||||
void DOS_SetupDevices(void);
|
void DOS_SetupDevices(void);
|
||||||
|
|
||||||
/* Execute and new process creation */
|
/* Execute and new process creation */
|
||||||
bool DOS_NewPSP(Bit16u pspseg,Bit16u size);
|
bool DOS_NewPSP(Bit16u pspseg);
|
||||||
bool DOS_ChildPSP(Bit16u pspseg,Bit16u size);
|
bool DOS_Execute(char * name,ParamBlock * block,Bit8u flags);
|
||||||
bool DOS_Execute(char * name,PhysPt block,Bit8u flags);
|
bool DOS_Terminate(bool tsr);
|
||||||
bool DOS_Terminate(bool tsr,Bit8u exitcode);
|
|
||||||
|
|
||||||
/* Memory Handling Routines */
|
/* Memory Handling Routines */
|
||||||
void DOS_SetupMemory(void);
|
void DOS_SetupMemory(void);
|
||||||
@ -163,65 +194,27 @@ bool DOS_ResizeMemory(Bit16u segment,Bit16u * blocks);
|
|||||||
bool DOS_FreeMemory(Bit16u segment);
|
bool DOS_FreeMemory(Bit16u segment);
|
||||||
void DOS_FreeProcessMemory(Bit16u pspseg);
|
void DOS_FreeProcessMemory(Bit16u pspseg);
|
||||||
Bit16u DOS_GetMemory(Bit16u pages);
|
Bit16u DOS_GetMemory(Bit16u pages);
|
||||||
bool DOS_SetMemAllocStrategy(Bit16u strat);
|
|
||||||
Bit16u DOS_GetMemAllocStrategy(void);
|
|
||||||
void DOS_BuildUMBChain(bool umb_active,bool ems_active);
|
|
||||||
bool DOS_LinkUMBsToMemChain(Bit16u linkstate);
|
|
||||||
|
|
||||||
/* FCB stuff */
|
|
||||||
bool DOS_FCBOpen(Bit16u seg,Bit16u offset);
|
|
||||||
bool DOS_FCBCreate(Bit16u seg,Bit16u offset);
|
|
||||||
bool DOS_FCBClose(Bit16u seg,Bit16u offset);
|
|
||||||
bool DOS_FCBFindFirst(Bit16u seg,Bit16u offset);
|
|
||||||
bool DOS_FCBFindNext(Bit16u seg,Bit16u offset);
|
|
||||||
Bit8u DOS_FCBRead(Bit16u seg,Bit16u offset, Bit16u numBlocks);
|
|
||||||
Bit8u DOS_FCBWrite(Bit16u seg,Bit16u offset,Bit16u numBlocks);
|
|
||||||
Bit8u DOS_FCBRandomRead(Bit16u seg,Bit16u offset,Bit16u numRec,bool restore);
|
|
||||||
Bit8u DOS_FCBRandomWrite(Bit16u seg,Bit16u offset,Bit16u numRec,bool restore);
|
|
||||||
bool DOS_FCBGetFileSize(Bit16u seg,Bit16u offset);
|
|
||||||
bool DOS_FCBDeleteFile(Bit16u seg,Bit16u offset);
|
|
||||||
bool DOS_FCBRenameFile(Bit16u seg, Bit16u offset);
|
|
||||||
void DOS_FCBSetRandomRecord(Bit16u seg, Bit16u offset);
|
|
||||||
Bit8u FCB_Parsename(Bit16u seg,Bit16u offset,Bit8u parser ,char *string, Bit8u *change);
|
|
||||||
bool DOS_GetAllocationInfo(Bit8u drive,Bit16u * _bytes_sector,Bit8u * _sectors_cluster,Bit16u * _total_clusters);
|
|
||||||
|
|
||||||
/* Extra DOS Interrupts */
|
/* Extra DOS Interrupts */
|
||||||
void DOS_SetupMisc(void);
|
void DOS_SetupMisc(void);
|
||||||
|
|
||||||
/* The DOS Tables */
|
/* The DOS Tables */
|
||||||
void DOS_SetupTables(void);
|
void DOS_SetupTables(void);
|
||||||
|
|
||||||
/* Internal DOS Setup Programs */
|
/* Internal DOS Setup Programs */
|
||||||
void DOS_SetupPrograms(void);
|
void DOS_SetupPrograms(void);
|
||||||
|
|
||||||
/* Initialize Keyboard Layout */
|
|
||||||
void DOS_KeyboardLayout_Init(Section* sec);
|
|
||||||
|
|
||||||
bool DOS_LayoutKey(Bitu key, Bit8u flags1, Bit8u flags2, Bit8u flags3);
|
INLINE Bit16u long2para(Bit32u size) {
|
||||||
|
|
||||||
enum {
|
|
||||||
KEYB_NOERROR=0,
|
|
||||||
KEYB_FILENOTFOUND,
|
|
||||||
KEYB_INVALIDFILE,
|
|
||||||
KEYB_LAYOUTNOTFOUND,
|
|
||||||
KEYB_INVALIDCPFILE
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE Bit16u long2para(Bit32u size) {
|
|
||||||
if (size>0xFFFF0) return 0xffff;
|
if (size>0xFFFF0) return 0xffff;
|
||||||
if (size&0xf) return (Bit16u)((size>>4)+1);
|
if (size&0xf) return (Bit16u)((size>>4)+1);
|
||||||
else return (Bit16u)(size>>4);
|
else return (Bit16u)(size>>4);
|
||||||
}
|
};
|
||||||
|
|
||||||
|
INLINE Bit8u RealHandle(Bit16u handle) {
|
||||||
static INLINE Bit16u DOS_PackTime(Bit16u hour,Bit16u min,Bit16u sec) {
|
PSP * psp=(PSP *)real_off(dos.psp,0);
|
||||||
return (hour&0x1f)<<11 | (min&0x3f) << 5 | ((sec/2)&0x1f);
|
if (handle>=psp->max_files) return DOS_FILES;
|
||||||
}
|
return mem_readb(Real2Phys(psp->file_table)+handle);
|
||||||
|
};
|
||||||
static INLINE Bit16u DOS_PackDate(Bit16u year,Bit16u mon,Bit16u day) {
|
|
||||||
return ((year-1980)&0x7f)<<9 | (mon&0x3f) << 5 | (day&0x1f);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Dos Error Codes */
|
/* Dos Error Codes */
|
||||||
#define DOSERR_NONE 0
|
#define DOSERR_NONE 0
|
||||||
@ -244,400 +237,39 @@ static INLINE Bit16u DOS_PackDate(Bit16u year,Bit16u mon,Bit16u day) {
|
|||||||
#define DOSERR_REMOVE_CURRENT_DIRECTORY 16
|
#define DOSERR_REMOVE_CURRENT_DIRECTORY 16
|
||||||
#define DOSERR_NOT_SAME_DEVICE 17
|
#define DOSERR_NOT_SAME_DEVICE 17
|
||||||
#define DOSERR_NO_MORE_FILES 18
|
#define DOSERR_NO_MORE_FILES 18
|
||||||
#define DOSERR_FILE_ALREADY_EXISTS 80
|
|
||||||
|
|
||||||
|
|
||||||
/* Remains some classes used to access certain things */
|
/* Remains some classes used to access certain things */
|
||||||
#define sOffset(s,m) ((char*)&(((s*)NULL)->m)-(char*)NULL)
|
class DOS_FCB {
|
||||||
#define sGet(s,m) GetIt(sizeof(((s *)&pt)->m),(PhysPt)sOffset(s,m))
|
|
||||||
#define sSave(s,m,val) SaveIt(sizeof(((s *)&pt)->m),(PhysPt)sOffset(s,m),val)
|
|
||||||
|
|
||||||
class MemStruct {
|
|
||||||
public:
|
public:
|
||||||
Bitu GetIt(Bitu size,PhysPt addr) {
|
DOS_FCB(PhysPt pt){
|
||||||
switch (size) {
|
off=pt;
|
||||||
case 1:return mem_readb(pt+addr);
|
|
||||||
case 2:return mem_readw(pt+addr);
|
|
||||||
case 4:return mem_readd(pt+addr);
|
|
||||||
}
|
}
|
||||||
return 0;
|
DOS_FCB(Bit16u seg, Bit16u offset){
|
||||||
|
off=Real2Phys(RealMake(seg,offset));
|
||||||
}
|
}
|
||||||
void SaveIt(Bitu size,PhysPt addr,Bitu val) {
|
void Set_drive(Bit8u a);
|
||||||
switch (size) {
|
void Set_filename(char* a); //writes an the first 8 bytes of a as the filename
|
||||||
case 1:mem_writeb(pt+addr,(Bit8u)val);break;
|
void Set_ext(char* a);
|
||||||
case 2:mem_writew(pt+addr,(Bit16u)val);break;
|
void Set_current_block(Bit16u a);
|
||||||
case 4:mem_writed(pt+addr,(Bit32u)val);break;
|
void Set_record_size(Bit16u a);
|
||||||
}
|
void Set_filesize(Bit32u a);
|
||||||
}
|
void Set_date(Bit16u a);
|
||||||
void SetPt(Bit16u seg) { pt=PhysMake(seg,0);}
|
void Set_time(Bit16u a);
|
||||||
void SetPt(Bit16u seg,Bit16u off) { pt=PhysMake(seg,off);}
|
// others nog yet handled
|
||||||
void SetPt(RealPt addr) { pt=Real2Phys(addr);}
|
Bit8u Get_drive(void);
|
||||||
protected:
|
void Get_filename(char* a);
|
||||||
PhysPt pt;
|
void Get_ext(char* a);
|
||||||
};
|
Bit16u Get_current_block(void);
|
||||||
|
Bit16u Get_record_size(void);
|
||||||
class DOS_PSP :public MemStruct {
|
Bit32u Get_filesize(void);
|
||||||
public:
|
Bit16u Get_date(void);
|
||||||
DOS_PSP (Bit16u segment) { SetPt(segment);seg=segment;};
|
Bit16u Get_time(void);
|
||||||
void MakeNew (Bit16u memSize);
|
|
||||||
void CopyFileTable (DOS_PSP* srcpsp,bool createchildpsp);
|
|
||||||
Bit16u FindFreeFileEntry (void);
|
|
||||||
void CloseFiles (void);
|
|
||||||
|
|
||||||
void SaveVectors (void);
|
|
||||||
void RestoreVectors (void);
|
|
||||||
void SetSize (Bit16u size) { sSave(sPSP,next_seg,size); };
|
|
||||||
Bit16u GetSize (void) { return (Bit16u)sGet(sPSP,next_seg); };
|
|
||||||
void SetEnvironment (Bit16u envseg) { sSave(sPSP,environment,envseg); };
|
|
||||||
Bit16u GetEnvironment (void) { return (Bit16u)sGet(sPSP,environment); };
|
|
||||||
Bit16u GetSegment (void) { return seg; };
|
|
||||||
void SetFileHandle (Bit16u index, Bit8u handle);
|
|
||||||
Bit8u GetFileHandle (Bit16u index);
|
|
||||||
void SetParent (Bit16u parent) { sSave(sPSP,psp_parent,parent); };
|
|
||||||
Bit16u GetParent (void) { return (Bit16u)sGet(sPSP,psp_parent); };
|
|
||||||
void SetStack (RealPt stackpt) { sSave(sPSP,stack,stackpt); };
|
|
||||||
RealPt GetStack (void) { return sGet(sPSP,stack); };
|
|
||||||
void SetInt22 (RealPt int22pt) { sSave(sPSP,int_22,int22pt); };
|
|
||||||
RealPt GetInt22 (void) { return sGet(sPSP,int_22); };
|
|
||||||
void SetFCB1 (RealPt src);
|
|
||||||
void SetFCB2 (RealPt src);
|
|
||||||
void SetCommandTail (RealPt src);
|
|
||||||
bool SetNumFiles (Bit16u fileNum);
|
|
||||||
Bit16u FindEntryByHandle (Bit8u handle);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef _MSC_VER
|
PhysPt off;
|
||||||
#pragma pack(1)
|
|
||||||
#endif
|
|
||||||
struct sPSP {
|
|
||||||
Bit8u exit[2]; /* CP/M-like exit poimt */
|
|
||||||
Bit16u next_seg; /* Segment of first byte beyond memory allocated or program */
|
|
||||||
Bit8u fill_1; /* single char fill */
|
|
||||||
Bit8u far_call; /* far call opcode */
|
|
||||||
RealPt cpm_entry; /* CPM Service Request address*/
|
|
||||||
RealPt int_22; /* Terminate Address */
|
|
||||||
RealPt int_23; /* Break Address */
|
|
||||||
RealPt int_24; /* Critical Error Address */
|
|
||||||
Bit16u psp_parent; /* Parent PSP Segment */
|
|
||||||
Bit8u files[20]; /* File Table - 0xff is unused */
|
|
||||||
Bit16u environment; /* Segment of evironment table */
|
|
||||||
RealPt stack; /* SS:SP Save point for int 0x21 calls */
|
|
||||||
Bit16u max_files; /* Maximum open files */
|
|
||||||
RealPt file_table; /* Pointer to File Table PSP:0x18 */
|
|
||||||
RealPt prev_psp; /* Pointer to previous PSP */
|
|
||||||
Bit8u interim_flag;
|
|
||||||
Bit8u truename_flag;
|
|
||||||
Bit16u nn_flags;
|
|
||||||
Bit16u dos_version;
|
|
||||||
Bit8u fill_2[14]; /* Lot's of unused stuff i can't care aboue */
|
|
||||||
Bit8u service[3]; /* INT 0x21 Service call int 0x21;retf; */
|
|
||||||
Bit8u fill_3[9]; /* This has some blocks with FCB info */
|
|
||||||
Bit8u fcb1[16]; /* first FCB */
|
|
||||||
Bit8u fcb2[16]; /* second FCB */
|
|
||||||
Bit8u fill_4[4]; /* unused */
|
|
||||||
CommandTail cmdtail;
|
|
||||||
} GCC_ATTRIBUTE(packed);
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma pack()
|
|
||||||
#endif
|
|
||||||
Bit16u seg;
|
|
||||||
public:
|
|
||||||
static Bit16u rootpsp;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class DOS_ParamBlock:public MemStruct {
|
|
||||||
public:
|
|
||||||
DOS_ParamBlock(PhysPt addr) {pt=addr;}
|
|
||||||
void Clear(void);
|
|
||||||
void LoadData(void);
|
|
||||||
void SaveData(void); /* Save it as an exec block */
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma pack (1)
|
|
||||||
#endif
|
|
||||||
struct sOverlay {
|
|
||||||
Bit16u loadseg;
|
|
||||||
Bit16u relocation;
|
|
||||||
} GCC_ATTRIBUTE(packed);
|
|
||||||
struct sExec {
|
|
||||||
Bit16u envseg;
|
|
||||||
RealPt cmdtail;
|
|
||||||
RealPt fcb1;
|
|
||||||
RealPt fcb2;
|
|
||||||
RealPt initsssp;
|
|
||||||
RealPt initcsip;
|
|
||||||
}GCC_ATTRIBUTE(packed);
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma pack()
|
|
||||||
#endif
|
|
||||||
sExec exec;
|
|
||||||
sOverlay overlay;
|
|
||||||
};
|
|
||||||
|
|
||||||
class DOS_InfoBlock:public MemStruct {
|
|
||||||
public:
|
|
||||||
DOS_InfoBlock () {};
|
|
||||||
void SetLocation(Bit16u seg);
|
|
||||||
void SetFirstMCB(Bit16u _first_mcb);
|
|
||||||
void SetBuffers(Bit16u x,Bit16u y);
|
|
||||||
void SetCurDirStruct(Bit32u _curdirstruct);
|
|
||||||
void SetFCBTable(Bit32u _fcbtable);
|
|
||||||
void SetDeviceChainStart(Bit32u _devchain);
|
|
||||||
void SetDiskBufferHeadPt(Bit32u _dbheadpt);
|
|
||||||
void SetStartOfUMBChain(Bit16u _umbstartseg);
|
|
||||||
void SetUMBChainState(Bit8u _umbchaining);
|
|
||||||
Bit16u GetStartOfUMBChain(void);
|
|
||||||
Bit8u GetUMBChainState(void);
|
|
||||||
RealPt GetPointer(void);
|
|
||||||
Bit32u GetDeviceChain(void);
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma pack(1)
|
|
||||||
#endif
|
|
||||||
struct sDIB {
|
|
||||||
Bit8u unknown1[4];
|
|
||||||
Bit16u magicWord; // -0x22 needs to be 1
|
|
||||||
Bit8u unknown2[8];
|
|
||||||
Bit16u regCXfrom5e; // -0x18 CX from last int21/ah=5e
|
|
||||||
Bit16u countLRUcache; // -0x16 LRU counter for FCB caching
|
|
||||||
Bit16u countLRUopens; // -0x14 LRU counter for FCB openings
|
|
||||||
Bit8u stuff[6]; // -0x12 some stuff, hopefully never used....
|
|
||||||
Bit16u sharingCount; // -0x0c sharing retry count
|
|
||||||
Bit16u sharingDelay; // -0x0a sharing retry delay
|
|
||||||
RealPt diskBufPtr; // -0x08 pointer to disk buffer
|
|
||||||
Bit16u ptrCONinput; // -0x04 pointer to con input
|
|
||||||
Bit16u firstMCB; // -0x02 first memory control block
|
|
||||||
RealPt firstDPB; // 0x00 first drive parameter block
|
|
||||||
RealPt firstFileTable; // 0x04 first system file table
|
|
||||||
RealPt activeClock; // 0x08 active clock device header
|
|
||||||
RealPt activeCon; // 0x0c active console device header
|
|
||||||
Bit16u maxSectorLength; // 0x10 maximum bytes per sector of any block device;
|
|
||||||
RealPt diskInfoBuffer; // 0x12 pointer to disk info buffer
|
|
||||||
RealPt curDirStructure; // 0x16 pointer to current array of directory structure
|
|
||||||
RealPt fcbTable; // 0x1a pointer to system FCB table
|
|
||||||
Bit16u protFCBs; // 0x1e protected fcbs
|
|
||||||
Bit8u blockDevices; // 0x20 installed block devices
|
|
||||||
Bit8u lastdrive; // 0x21 lastdrive
|
|
||||||
Bit32u nulNextDriver; // 0x22 NUL driver next pointer
|
|
||||||
Bit16u nulAttributes; // 0x26 NUL driver aattributes
|
|
||||||
Bit32u nulStrategy; // 0x28 NUL driver strategy routine
|
|
||||||
Bit8u nulString[8]; // 0x2c NUL driver name string
|
|
||||||
Bit8u joindedDrives; // 0x34 joined drives
|
|
||||||
Bit16u specialCodeSeg; // 0x35 special code segment
|
|
||||||
RealPt setverPtr; // 0x37 pointer to setver
|
|
||||||
Bit16u a20FixOfs; // 0x3b a20 fix routine offset
|
|
||||||
Bit16u pspLastIfHMA; // 0x3d psp of last program (if dos in hma)
|
|
||||||
Bit16u buffers_x; // 0x3f x in BUFFERS x,y
|
|
||||||
Bit16u buffers_y; // 0x41 y in BUFFERS x,y
|
|
||||||
Bit8u bootDrive; // 0x43 boot drive
|
|
||||||
Bit8u useDwordMov; // 0x44 use dword moves
|
|
||||||
Bit16u extendedSize; // 0x45 size of extended memory
|
|
||||||
Bit32u diskBufferHeadPt; // 0x47 pointer to least-recently used buffer header
|
|
||||||
Bit16u dirtyDiskBuffers; // 0x4b number of dirty disk buffers
|
|
||||||
Bit32u lookaheadBufPt; // 0x4d pointer to lookahead buffer
|
|
||||||
Bit16u lookaheadBufNumber; // 0x51 number of lookahead buffers
|
|
||||||
Bit8u bufferLocation; // 0x53 workspace buffer location
|
|
||||||
Bit32u workspaceBuffer; // 0x54 pointer to workspace buffer
|
|
||||||
Bit8u unknown3[11]; // 0x58
|
|
||||||
Bit8u chainingUMB; // 0x63 bit0: UMB chain linked to MCB chain
|
|
||||||
Bit16u minMemForExec; // 0x64 minimum paragraphs needed for current program
|
|
||||||
Bit16u startOfUMBChain; // 0x66 segment of first UMB-MCB
|
|
||||||
Bit16u memAllocScanStart; // 0x68 start paragraph for memory allocation
|
|
||||||
} GCC_ATTRIBUTE(packed);
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma pack ()
|
|
||||||
#endif
|
|
||||||
Bit16u seg;
|
|
||||||
};
|
|
||||||
|
|
||||||
class DOS_DTA:public MemStruct{
|
|
||||||
public:
|
|
||||||
DOS_DTA(RealPt addr) { SetPt(addr); }
|
|
||||||
|
|
||||||
void SetupSearch(Bit8u _sdrive,Bit8u _sattr,char * _pattern);
|
|
||||||
void SetResult(const char * _name,Bit32u _size,Bit16u _date,Bit16u _time,Bit8u _attr);
|
|
||||||
|
|
||||||
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); };
|
|
||||||
void SetDirIDCluster(Bit16u entry) { sSave(sDTA,dirCluster,entry); };
|
|
||||||
Bit16u GetDirID(void) { return (Bit16u)sGet(sDTA,dirID); };
|
|
||||||
Bit16u GetDirIDCluster(void) { return (Bit16u)sGet(sDTA,dirCluster); };
|
|
||||||
private:
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma pack(1)
|
|
||||||
#endif
|
|
||||||
struct sDTA {
|
|
||||||
Bit8u sdrive; /* The Drive the search is taking place */
|
|
||||||
Bit8u sname[8]; /* The Search pattern for the filename */
|
|
||||||
Bit8u sext[3]; /* The Search pattern for the extenstion */
|
|
||||||
Bit8u sattr; /* The Attributes that need to be found */
|
|
||||||
Bit16u dirID; /* custom: dir-search ID for multiple searches at the same time */
|
|
||||||
Bit16u dirCluster; /* custom (drive_fat only): cluster number for multiple searches at the same time */
|
|
||||||
Bit8u fill[4];
|
|
||||||
Bit8u attr;
|
|
||||||
Bit16u time;
|
|
||||||
Bit16u date;
|
|
||||||
Bit32u size;
|
|
||||||
char name[DOS_NAMELENGTH_ASCII];
|
|
||||||
} GCC_ATTRIBUTE(packed);
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma pack()
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
class DOS_FCB: public MemStruct {
|
|
||||||
public:
|
|
||||||
DOS_FCB(Bit16u seg,Bit16u off);
|
|
||||||
void Create(bool _extended);
|
|
||||||
void SetName(Bit8u _drive,char * _fname,char * _ext);
|
|
||||||
void SetSizeDateTime(Bit32u _size,Bit16u _date,Bit16u _time);
|
|
||||||
void GetSizeDateTime(Bit32u & _size,Bit16u & _date,Bit16u & _time);
|
|
||||||
void GetName(char * fillname);
|
|
||||||
void FileOpen(Bit8u _fhandle);
|
|
||||||
void FileClose(Bit8u & _fhandle);
|
|
||||||
void GetRecord(Bit16u & _cur_block,Bit8u & _cur_rec);
|
|
||||||
void SetRecord(Bit16u _cur_block,Bit8u _cur_rec);
|
|
||||||
void GetSeqData(Bit8u & _fhandle,Bit16u & _rec_size);
|
|
||||||
void GetRandom(Bit32u & _random);
|
|
||||||
void SetRandom(Bit32u _random);
|
|
||||||
Bit8u GetDrive(void);
|
|
||||||
bool Extended(void);
|
|
||||||
void GetAttr(Bit8u & attr);
|
|
||||||
void SetAttr(Bit8u attr);
|
|
||||||
bool Valid(void);
|
|
||||||
private:
|
|
||||||
bool extended;
|
|
||||||
PhysPt real_pt;
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma pack (1)
|
|
||||||
#endif
|
|
||||||
struct sFCB {
|
|
||||||
Bit8u drive; /* Drive number 0=default, 1=A, etc */
|
|
||||||
Bit8u filename[8]; /* Space padded name */
|
|
||||||
Bit8u ext[3]; /* Space padded extension */
|
|
||||||
Bit16u cur_block; /* Current Block */
|
|
||||||
Bit16u rec_size; /* Logical record size */
|
|
||||||
Bit32u filesize; /* File Size */
|
|
||||||
Bit16u date;
|
|
||||||
Bit16u time;
|
|
||||||
/* Reserved Block should be 8 bytes */
|
|
||||||
Bit8u sft_entries;
|
|
||||||
Bit8u share_attributes;
|
|
||||||
Bit8u extra_info;
|
|
||||||
Bit8u file_handle;
|
|
||||||
Bit8u reserved[4];
|
|
||||||
/* end */
|
|
||||||
Bit8u cur_rec; /* Current record in current block */
|
|
||||||
Bit32u rndm; /* Current relative record number */
|
|
||||||
} GCC_ATTRIBUTE(packed);
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma pack ()
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
class DOS_MCB : public MemStruct{
|
|
||||||
public:
|
|
||||||
DOS_MCB(Bit16u seg) { SetPt(seg); }
|
|
||||||
void SetFileName(char const * const _name) { MEM_BlockWrite(pt+offsetof(sMCB,filename),_name,8); }
|
|
||||||
void GetFileName(char * const _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 (Bit8u)sGet(sMCB,type);}
|
|
||||||
Bit16u GetSize(void) { return (Bit16u)sGet(sMCB,size);}
|
|
||||||
Bit16u GetPSPSeg(void) { return (Bit16u)sGet(sMCB,psp_segment);}
|
|
||||||
private:
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma pack (1)
|
|
||||||
#endif
|
|
||||||
struct sMCB {
|
|
||||||
Bit8u type;
|
|
||||||
Bit16u psp_segment;
|
|
||||||
Bit16u size;
|
|
||||||
Bit8u unused[3];
|
|
||||||
Bit8u filename[8];
|
|
||||||
} GCC_ATTRIBUTE(packed);
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma pack ()
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
class DOS_SDA : public MemStruct {
|
|
||||||
public:
|
|
||||||
DOS_SDA(Bit16u _seg,Bit16u _offs) { SetPt(_seg,_offs); }
|
|
||||||
void Init();
|
|
||||||
void SetDrive(Bit8u _drive) { sSave(sSDA,current_drive, _drive); }
|
|
||||||
void SetDTA(Bit32u _dta) { sSave(sSDA,current_dta, _dta); }
|
|
||||||
void SetPSP(Bit16u _psp) { sSave(sSDA,current_psp, _psp); }
|
|
||||||
Bit8u GetDrive(void) { return (Bit8u)sGet(sSDA,current_drive); }
|
|
||||||
Bit16u GetPSP(void) { return (Bit16u)sGet(sSDA,current_psp); }
|
|
||||||
Bit32u GetDTA(void) { return (Bit32u)sGet(sSDA,current_dta); }
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma pack (1)
|
|
||||||
#endif
|
|
||||||
struct sSDA {
|
|
||||||
Bit8u crit_error_flag; /* 0x00 Critical Error Flag */
|
|
||||||
Bit8u inDOS_flag; /* 0x01 InDOS flag (count of active INT 21 calls) */
|
|
||||||
Bit8u drive_crit_error; /* 0x02 Drive on which current critical error occurred or FFh */
|
|
||||||
Bit8u locus_of_last_error; /* 0x03 locus of last error */
|
|
||||||
Bit16u extended_error_code; /* 0x04 extended error code of last error */
|
|
||||||
Bit8u suggested_action; /* 0x06 suggested action for last error */
|
|
||||||
Bit8u error_class; /* 0x07 class of last error*/
|
|
||||||
Bit32u last_error_pointer; /* 0x08 ES:DI pointer for last error */
|
|
||||||
Bit32u current_dta; /* 0x0C current DTA (Disk Transfer Address) */
|
|
||||||
Bit16u current_psp; /* 0x10 current PSP */
|
|
||||||
Bit16u sp_int_23; /* 0x12 stores SP across an INT 23 */
|
|
||||||
Bit16u return_code; /* 0x14 return code from last process termination (zerod after reading with AH=4Dh) */
|
|
||||||
Bit8u current_drive; /* 0x16 current drive */
|
|
||||||
Bit8u extended_break_flag; /* 0x17 extended break flag */
|
|
||||||
Bit8u fill[2]; /* 0x18 flag: code page switching || flag: copy of previous byte in case of INT 24 Abort*/
|
|
||||||
} GCC_ATTRIBUTE(packed);
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma pack()
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
extern DOS_InfoBlock dos_infoblock;
|
|
||||||
|
|
||||||
struct DOS_Block {
|
|
||||||
DOS_Date date;
|
|
||||||
DOS_Version version;
|
|
||||||
Bit16u firstMCB;
|
|
||||||
Bit16u errorcode;
|
|
||||||
Bit16u psp(){return DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).GetPSP();};
|
|
||||||
void psp(Bit16u _seg){ DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).SetPSP(_seg);};
|
|
||||||
Bit16u env;
|
|
||||||
RealPt cpmentry;
|
|
||||||
RealPt dta(){return DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).GetDTA();};
|
|
||||||
void dta(RealPt _dta){DOS_SDA(DOS_SDA_SEG,DOS_SDA_OFS).SetDTA(_dta);};
|
|
||||||
Bit8u return_code,return_mode;
|
|
||||||
|
|
||||||
Bit8u current_drive;
|
|
||||||
bool verify;
|
|
||||||
bool breakcheck;
|
|
||||||
bool echo; // if set to true dev_con::read will echo input
|
|
||||||
struct {
|
|
||||||
RealPt mediaid;
|
|
||||||
RealPt tempdta;
|
|
||||||
RealPt tempdta_fcbdelete;
|
|
||||||
RealPt dbcs;
|
|
||||||
RealPt filenamechar;
|
|
||||||
RealPt collatingseq;
|
|
||||||
Bit8u* country;//Will be copied to dos memory. resides in real mem
|
|
||||||
Bit16u dpb; //Fake Disk parameter system using only the first entry so the drive letter matches
|
|
||||||
} tables;
|
|
||||||
Bit16u loaded_codepage;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern DOS_Block dos;
|
|
||||||
|
|
||||||
static Bit8u RealHandle(Bit16u handle) {
|
|
||||||
DOS_PSP psp(dos.psp());
|
|
||||||
return psp.GetFileHandle(handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2009 The DOSBox Team
|
* Copyright (C) 2002 The DOSBox Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -9,37 +9,21 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Library General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: dos_system.h,v 1.47 2009/03/04 21:08:22 c2woody Exp $ */
|
#ifndef DOSSYSTEM_H_
|
||||||
|
#define DOSSYSTEM_H_
|
||||||
|
|
||||||
#ifndef DOSBOX_DOS_SYSTEM_H
|
#include <dosbox.h>
|
||||||
#define DOSBOX_DOS_SYSTEM_H
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#ifndef DOSBOX_DOSBOX_H
|
|
||||||
#include "dosbox.h"
|
|
||||||
#endif
|
|
||||||
#ifndef DOSBOX_CROSS_H
|
|
||||||
#include "cross.h"
|
|
||||||
#endif
|
|
||||||
#ifndef DOSBOX_SUPPORT_H
|
|
||||||
#include "support.h"
|
|
||||||
#endif
|
|
||||||
#ifndef DOSBOX_MEM_H
|
|
||||||
#include "mem.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define DOS_NAMELENGTH 12
|
#define DOS_NAMELENGTH 12
|
||||||
#define DOS_NAMELENGTH_ASCII (DOS_NAMELENGTH+1)
|
#define DOS_DIRDEPTH 16
|
||||||
#define DOS_FCBNAME 15
|
#define DOS_PATHLENGTH (DOS_DIRDEPTH+1)*(DOS_NAMELENGTH+2)
|
||||||
#define DOS_DIRDEPTH 8
|
|
||||||
#define DOS_PATHLENGTH 80
|
|
||||||
#define DOS_TEMPSIZE 1024
|
#define DOS_TEMPSIZE 1024
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@ -48,206 +32,62 @@ enum {
|
|||||||
DOS_ATTR_SYSTEM= 0x04,
|
DOS_ATTR_SYSTEM= 0x04,
|
||||||
DOS_ATTR_VOLUME= 0x08,
|
DOS_ATTR_VOLUME= 0x08,
|
||||||
DOS_ATTR_DIRECTORY= 0x10,
|
DOS_ATTR_DIRECTORY= 0x10,
|
||||||
DOS_ATTR_ARCHIVE= 0x20,
|
DOS_ATTR_ARCHIVE= 0x20
|
||||||
DOS_ATTR_DEVICE= 0x40
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FileStat_Block {
|
#pragma pack (1)
|
||||||
Bit32u size;
|
struct DTA_FindBlock {
|
||||||
|
Bit8u sdrive; /* The Drive the search is taking place */
|
||||||
|
Bit16u sattr; /* The attributes that need to be found */
|
||||||
|
Bit8u fill[18];
|
||||||
|
Bit8u attr;
|
||||||
Bit16u time;
|
Bit16u time;
|
||||||
Bit16u date;
|
Bit16u date;
|
||||||
Bit16u attr;
|
Bit32u size;
|
||||||
|
char name[DOS_NAMELENGTH];
|
||||||
};
|
};
|
||||||
|
#pragma pack ()
|
||||||
class DOS_DTA;
|
|
||||||
|
|
||||||
class DOS_File {
|
class DOS_File {
|
||||||
public:
|
public:
|
||||||
DOS_File():flags(0) { name=0; refCtr = 0; hdrive=0xff; };
|
|
||||||
DOS_File(const DOS_File& orig);
|
|
||||||
DOS_File & operator= (const DOS_File & orig);
|
|
||||||
virtual ~DOS_File(){if(name) delete [] name;};
|
|
||||||
virtual bool Read(Bit8u * data,Bit16u * size)=0;
|
virtual bool Read(Bit8u * data,Bit16u * size)=0;
|
||||||
virtual bool Write(Bit8u * data,Bit16u * size)=0;
|
virtual bool Write(Bit8u * data,Bit16u * size)=0;
|
||||||
virtual bool Seek(Bit32u * pos,Bit32u type)=0;
|
virtual bool Seek(Bit32u * pos,Bit32u type)=0;
|
||||||
virtual bool Close()=0;
|
virtual bool Close()=0;
|
||||||
virtual Bit16u GetInformation(void)=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); }
|
Bit8u type;Bit32u flags;
|
||||||
virtual char* GetName(void) { return name; };
|
|
||||||
virtual bool IsOpen() { return open; };
|
|
||||||
virtual bool IsName(const char* _name) { if (!name) return false; return strcasecmp(name,_name)==0; };
|
|
||||||
virtual void AddRef() { refCtr++; };
|
|
||||||
virtual Bits RemoveRef() { return --refCtr; };
|
|
||||||
virtual bool UpdateDateTimeFromHost() { return true; }
|
|
||||||
void SetDrive(Bit8u drv) { hdrive=drv;}
|
|
||||||
Bit8u GetDrive(void) { return hdrive;}
|
|
||||||
Bit32u flags;
|
|
||||||
Bit16u time;
|
|
||||||
Bit16u date;
|
|
||||||
Bit16u attr;
|
|
||||||
Bits refCtr;
|
|
||||||
bool open;
|
|
||||||
char* name;
|
|
||||||
/* Some Device Specific Stuff */
|
/* Some Device Specific Stuff */
|
||||||
private:
|
|
||||||
Bit8u hdrive;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class DOS_Device : public DOS_File {
|
class DOS_Device : public DOS_File {
|
||||||
public:
|
public:
|
||||||
DOS_Device(const DOS_Device& orig):DOS_File(orig) {
|
/* Some Device Specific Stuff */
|
||||||
devnum=orig.devnum;
|
char * name;
|
||||||
open=true;
|
Bit8u fhandle;
|
||||||
}
|
|
||||||
DOS_Device & operator= (const DOS_Device & orig) {
|
|
||||||
DOS_File::operator=(orig);
|
|
||||||
devnum=orig.devnum;
|
|
||||||
open=true;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
DOS_Device():DOS_File(),devnum(0){};
|
|
||||||
virtual bool Read(Bit8u * data,Bit16u * size);
|
|
||||||
virtual bool Write(Bit8u * data,Bit16u * size);
|
|
||||||
virtual bool Seek(Bit32u * pos,Bit32u type);
|
|
||||||
virtual bool Close();
|
|
||||||
virtual Bit16u GetInformation(void);
|
|
||||||
virtual bool ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode);
|
|
||||||
virtual bool WriteToControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retcode);
|
|
||||||
void SetDeviceNumber(Bitu num) { devnum=num;}
|
|
||||||
private:
|
|
||||||
Bitu devnum;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The following variable can be lowered to free up some memory.
|
|
||||||
* The negative side effect: The stored searches will be turned over faster.
|
|
||||||
* Should not have impact on systems with few directory entries. */
|
|
||||||
#define MAX_OPENDIRS 2048
|
|
||||||
//Can be high as it's only storage (16 bit variable)
|
|
||||||
|
|
||||||
class DOS_Drive_Cache {
|
|
||||||
public:
|
|
||||||
DOS_Drive_Cache (void);
|
|
||||||
DOS_Drive_Cache (const char* path);
|
|
||||||
~DOS_Drive_Cache (void);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
bool FindFirst (char* path, Bitu& id);
|
|
||||||
bool FindNext (Bitu id, char* &result);
|
|
||||||
|
|
||||||
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);
|
|
||||||
void SetLabel (const char* name,bool cdrom,bool allowupdate);
|
|
||||||
char* GetLabel (void) { return label; };
|
|
||||||
|
|
||||||
class CFileInfo {
|
|
||||||
public:
|
|
||||||
CFileInfo(void) {
|
|
||||||
orgname[0] = shortname[0] = 0;
|
|
||||||
nextEntry = shortNr = 0;
|
|
||||||
isDir = false;
|
|
||||||
}
|
|
||||||
~CFileInfo(void) {
|
|
||||||
for (Bit32u i=0; i<fileList.size(); i++) delete fileList[i];
|
|
||||||
fileList.clear();
|
|
||||||
longNameList.clear();
|
|
||||||
};
|
|
||||||
char orgname [CROSS_LEN];
|
|
||||||
char shortname [DOS_NAMELENGTH_ASCII];
|
|
||||||
bool isDir;
|
|
||||||
Bitu nextEntry;
|
|
||||||
Bitu shortNr;
|
|
||||||
// contents
|
|
||||||
std::vector<CFileInfo*> fileList;
|
|
||||||
std::vector<CFileInfo*> longNameList;
|
|
||||||
};
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
bool RemoveTrailingDot (char* shortname);
|
|
||||||
Bits GetLongName (CFileInfo* info, char* shortname);
|
|
||||||
void CreateShortName (CFileInfo* dir, CFileInfo* info);
|
|
||||||
Bitu CreateShortNameID (CFileInfo* dir, const char* name);
|
|
||||||
int CompareShortname (const char* compareName, const char* shortName);
|
|
||||||
bool SetResult (CFileInfo* dir, char * &result, Bitu entryNr);
|
|
||||||
bool IsCachedIn (CFileInfo* dir);
|
|
||||||
CFileInfo* FindDirInfo (const char* path, char* expandedPath);
|
|
||||||
bool RemoveSpaces (char* str);
|
|
||||||
bool OpenDir (CFileInfo* dir, const char* path, Bit16u& id);
|
|
||||||
void CreateEntry (CFileInfo* dir, const char* name, bool query_directory);
|
|
||||||
void CopyEntry (CFileInfo* dir, CFileInfo* from);
|
|
||||||
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];
|
|
||||||
CFileInfo* dirFindFirst [MAX_OPENDIRS];
|
|
||||||
Bitu nextFreeFindFirst;
|
|
||||||
|
|
||||||
char label [CROSS_LEN];
|
|
||||||
bool updatelabel;
|
|
||||||
};
|
|
||||||
|
|
||||||
class DOS_Drive {
|
class DOS_Drive {
|
||||||
public:
|
public:
|
||||||
DOS_Drive();
|
DOS_Drive();
|
||||||
virtual ~DOS_Drive(){};
|
|
||||||
virtual bool FileOpen(DOS_File * * file,char * name,Bit32u flags)=0;
|
virtual bool FileOpen(DOS_File * * file,char * name,Bit32u flags)=0;
|
||||||
virtual bool FileCreate(DOS_File * * file,char * name,Bit16u attributes)=0;
|
virtual bool FileCreate(DOS_File * * file,char * name,Bit16u attributes)=0;
|
||||||
virtual bool FileUnlink(char * _name)=0;
|
virtual bool FileUnlink(char * name)=0;
|
||||||
virtual bool RemoveDir(char * _dir)=0;
|
virtual bool RemoveDir(char * dir)=0;
|
||||||
virtual bool MakeDir(char * _dir)=0;
|
virtual bool MakeDir(char * dir)=0;
|
||||||
virtual bool TestDir(char * _dir)=0;
|
virtual bool TestDir(char * dir)=0;
|
||||||
virtual bool FindFirst(char * _dir,DOS_DTA & dta,bool fcb_findfirst=false)=0;
|
virtual bool FindFirst(char * search,DTA_FindBlock * dta)=0;
|
||||||
virtual bool FindNext(DOS_DTA & dta)=0;
|
virtual bool FindNext(DTA_FindBlock * dta)=0;
|
||||||
virtual bool GetFileAttr(char * name,Bit16u * attr)=0;
|
virtual bool GetFileAttr(char * name,Bit16u * attr)=0;
|
||||||
virtual bool Rename(char * oldname,char * newname)=0;
|
virtual bool Rename(char * oldname,char * newname)=0;
|
||||||
virtual bool AllocationInfo(Bit16u * _bytes_sector,Bit8u * _sectors_cluster,Bit16u * _total_clusters,Bit16u * _free_clusters)=0;
|
virtual bool FreeSpace(Bit16u * bytes,Bit16u * sectors,Bit16u * clusters,Bit16u * free)=0;
|
||||||
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(); };
|
|
||||||
virtual bool isRemote(void)=0;
|
|
||||||
virtual bool isRemovable(void)=0;
|
|
||||||
virtual Bits UnMount(void)=0;
|
|
||||||
|
|
||||||
char * GetInfo(void);
|
char * GetInfo(void);
|
||||||
char curdir[DOS_PATHLENGTH];
|
char curdir[DOS_PATHLENGTH];
|
||||||
char info[256];
|
char info[256];
|
||||||
/* Can be overridden for example in iso images */
|
|
||||||
virtual char const * GetLabel(){return dirCache.GetLabel();};
|
|
||||||
|
|
||||||
DOS_Drive_Cache dirCache;
|
|
||||||
|
|
||||||
// disk cycling functionality (request resources)
|
|
||||||
virtual void Activate(void) {};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum { OPEN_READ=0,OPEN_WRITE=1,OPEN_READWRITE=2, DOS_NOT_INHERIT=128};
|
enum { OPEN_READ=0,OPEN_WRITE=1,OPEN_READWRITE=2 };
|
||||||
enum { DOS_SEEK_SET=0,DOS_SEEK_CUR=1,DOS_SEEK_END=2};
|
enum { DOS_SEEK_SET=0,DOS_SEEK_CUR=1,DOS_SEEK_END=2};
|
||||||
|
|
||||||
|
|
||||||
@ -258,12 +98,8 @@ enum { DOS_SEEK_SET=0,DOS_SEEK_CUR=1,DOS_SEEK_END=2};
|
|||||||
|
|
||||||
typedef bool (MultiplexHandler)(void);
|
typedef bool (MultiplexHandler)(void);
|
||||||
void DOS_AddMultiplexHandler(MultiplexHandler * handler);
|
void DOS_AddMultiplexHandler(MultiplexHandler * handler);
|
||||||
void DOS_DelMultiplexHandler(MultiplexHandler * handler);
|
|
||||||
|
|
||||||
/* AddDevice stores the pointer to a created device */
|
|
||||||
void DOS_AddDevice(DOS_Device * adddev);
|
void DOS_AddDevice(DOS_Device * adddev);
|
||||||
/* DelDevice destroys the device that is pointed to. */
|
void VFILE_Register(char * name,Bit8u * data,Bit32u size);
|
||||||
void DOS_DelDevice(DOS_Device * dev);
|
|
||||||
|
|
||||||
void VFILE_Register(const char * name,Bit8u * data,Bit32u size);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2008 The DOSBox Team
|
* Copyright (C) 2002 The DOSBox Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -9,68 +9,55 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Library General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: dosbox.h,v 1.31 2008/01/09 20:34:21 c2woody Exp $ */
|
#if !defined __DOSBOX_H
|
||||||
|
#define __DOSBOX_H
|
||||||
|
|
||||||
#ifndef DOSBOX_DOSBOX_H
|
typedef unsigned char Bit8u;
|
||||||
#define DOSBOX_DOSBOX_H
|
typedef signed char Bit8s;
|
||||||
|
typedef unsigned short Bit16u;
|
||||||
|
typedef signed short Bit16s;
|
||||||
|
typedef unsigned long Bit32u;
|
||||||
|
typedef signed long Bit32s;
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
typedef unsigned __int64 Bit64u;
|
||||||
|
typedef signed __int64 Bit64s;
|
||||||
|
#else
|
||||||
|
typedef unsigned long long int Bit64u;
|
||||||
|
typedef signed long long int Bit64s;
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "config.h"
|
typedef unsigned int Bitu;
|
||||||
|
typedef signed int Bits;
|
||||||
|
|
||||||
void E_Exit(const char * message,...) GCC_ATTRIBUTE( __format__(__printf__, 1, 2));
|
#include <stddef.h>
|
||||||
|
|
||||||
void MSG_Add(const char*,const char*); //add messages to the internal langaugefile
|
void E_Exit(char * message,...);
|
||||||
const char* MSG_Get(char const *); //get messages from the internal langaugafile
|
|
||||||
|
void S_Warn(char * message,...);
|
||||||
|
|
||||||
|
|
||||||
|
#include "../settings.h" /* General extra setting */
|
||||||
|
#if defined (_MSC_VER)
|
||||||
|
#include "../src/platform/visualc/config.h"
|
||||||
|
#else
|
||||||
|
#include "../config.h"
|
||||||
|
#define INLINE inline
|
||||||
|
#endif
|
||||||
|
|
||||||
class Section;
|
|
||||||
|
|
||||||
typedef Bitu (LoopHandler)(void);
|
typedef Bitu (LoopHandler)(void);
|
||||||
|
|
||||||
void DOSBOX_RunMachine();
|
void DOSBOX_RunMachine();
|
||||||
void DOSBOX_SetLoop(LoopHandler * handler);
|
void DOSBOX_SetLoop(LoopHandler * handler);
|
||||||
void DOSBOX_SetNormalLoop();
|
|
||||||
|
|
||||||
void DOSBOX_Init(void);
|
void DOSBOX_Init(int argc, char* argv[]);
|
||||||
|
void DOSBOX_StartUp(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
class Config;
|
|
||||||
extern Config * control;
|
|
||||||
|
|
||||||
enum MachineType {
|
|
||||||
MCH_HERC,
|
|
||||||
MCH_CGA,
|
|
||||||
MCH_TANDY,
|
|
||||||
MCH_PCJR,
|
|
||||||
MCH_EGA,
|
|
||||||
MCH_VGA
|
|
||||||
};
|
|
||||||
|
|
||||||
enum SVGACards {
|
|
||||||
SVGA_None,
|
|
||||||
SVGA_S3Trio,
|
|
||||||
SVGA_TsengET4K,
|
|
||||||
SVGA_TsengET3K,
|
|
||||||
SVGA_ParadisePVGA1A
|
|
||||||
};
|
|
||||||
|
|
||||||
extern SVGACards svgaCard;
|
|
||||||
extern MachineType machine;
|
|
||||||
extern bool SDLNetInited;
|
|
||||||
|
|
||||||
#define IS_TANDY_ARCH ((machine==MCH_TANDY) || (machine==MCH_PCJR))
|
|
||||||
#define IS_EGAVGA_ARCH ((machine==MCH_EGA) || (machine==MCH_VGA))
|
|
||||||
#define IS_VGA_ARCH (machine==MCH_VGA)
|
|
||||||
#define TANDY_ARCH_CASE MCH_TANDY: case MCH_PCJR
|
|
||||||
#define EGAVGA_ARCH_CASE MCH_EGA: case MCH_VGA
|
|
||||||
#define VGA_ARCH_CASE MCH_VGA
|
|
||||||
|
|
||||||
#ifndef DOSBOX_LOGGING_H
|
|
||||||
#include "logging.h"
|
|
||||||
#endif // the logging system.
|
|
||||||
|
|
||||||
#endif /* DOSBOX_DOSBOX_H */
|
|
||||||
|
153
include/fpu.h
153
include/fpu.h
@ -1,154 +1 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2002-2007 The DOSBox Team
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef DOSBOX_FPU_H
|
|
||||||
#define DOSBOX_FPU_H
|
|
||||||
|
|
||||||
#ifndef DOSBOX_MEM_H
|
|
||||||
#include "mem.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void FPU_ESC0_Normal(Bitu rm);
|
|
||||||
void FPU_ESC0_EA(Bitu func,PhysPt ea);
|
|
||||||
void FPU_ESC1_Normal(Bitu rm);
|
|
||||||
void FPU_ESC1_EA(Bitu func,PhysPt ea);
|
|
||||||
void FPU_ESC2_Normal(Bitu rm);
|
|
||||||
void FPU_ESC2_EA(Bitu func,PhysPt ea);
|
|
||||||
void FPU_ESC3_Normal(Bitu rm);
|
|
||||||
void FPU_ESC3_EA(Bitu func,PhysPt ea);
|
|
||||||
void FPU_ESC4_Normal(Bitu rm);
|
|
||||||
void FPU_ESC4_EA(Bitu func,PhysPt ea);
|
|
||||||
void FPU_ESC5_Normal(Bitu rm);
|
|
||||||
void FPU_ESC5_EA(Bitu func,PhysPt ea);
|
|
||||||
void FPU_ESC6_Normal(Bitu rm);
|
|
||||||
void FPU_ESC6_EA(Bitu func,PhysPt ea);
|
|
||||||
void FPU_ESC7_Normal(Bitu rm);
|
|
||||||
void FPU_ESC7_EA(Bitu func,PhysPt ea);
|
|
||||||
|
|
||||||
|
|
||||||
typedef union {
|
|
||||||
double d;
|
|
||||||
#ifndef WORDS_BIGENDIAN
|
|
||||||
struct {
|
|
||||||
Bit32u lower;
|
|
||||||
Bit32s upper;
|
|
||||||
} l;
|
|
||||||
#else
|
|
||||||
struct {
|
|
||||||
Bit32s upper;
|
|
||||||
Bit32u lower;
|
|
||||||
} l;
|
|
||||||
#endif
|
|
||||||
Bit64s ll;
|
|
||||||
} FPU_Reg;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
Bit32u m1;
|
|
||||||
Bit32u m2;
|
|
||||||
Bit16u m3;
|
|
||||||
|
|
||||||
Bit16u d1;
|
|
||||||
Bit32u d2;
|
|
||||||
} FPU_P_Reg;
|
|
||||||
|
|
||||||
enum FPU_Tag {
|
|
||||||
TAG_Valid = 0,
|
|
||||||
TAG_Zero = 1,
|
|
||||||
TAG_Weird = 2,
|
|
||||||
TAG_Empty = 3
|
|
||||||
};
|
|
||||||
|
|
||||||
enum FPU_Round {
|
|
||||||
ROUND_Nearest = 0,
|
|
||||||
ROUND_Down = 1,
|
|
||||||
ROUND_Up = 2,
|
|
||||||
ROUND_Chop = 3
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
FPU_Reg regs[9];
|
|
||||||
FPU_P_Reg p_regs[9];
|
|
||||||
FPU_Tag tags[9];
|
|
||||||
Bit16u cw,cw_mask_all;
|
|
||||||
Bit16u sw;
|
|
||||||
Bitu top;
|
|
||||||
FPU_Round round;
|
|
||||||
} FPU_rec;
|
|
||||||
|
|
||||||
|
|
||||||
//get pi from a real library
|
|
||||||
#define PI 3.14159265358979323846
|
|
||||||
#define L2E 1.4426950408889634
|
|
||||||
#define L2T 3.3219280948873623
|
|
||||||
#define LN2 0.69314718055994531
|
|
||||||
#define LG2 0.3010299956639812
|
|
||||||
|
|
||||||
|
|
||||||
extern FPU_rec fpu;
|
|
||||||
|
|
||||||
#define TOP fpu.top
|
|
||||||
#define STV(i) ( (fpu.top+ (i) ) & 7 )
|
|
||||||
|
|
||||||
|
|
||||||
Bit16u FPU_GetTag(void);
|
|
||||||
void FPU_FLDCW(PhysPt addr);
|
|
||||||
|
|
||||||
static INLINE void FPU_SetTag(Bit16u tag){
|
|
||||||
for(Bitu i=0;i<8;i++)
|
|
||||||
fpu.tags[i] = static_cast<FPU_Tag>((tag >>(2*i))&3);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void FPU_SetCW(Bitu word){
|
|
||||||
fpu.cw = (Bit16u)word;
|
|
||||||
fpu.cw_mask_all = (Bit16u)(word | 0x3f);
|
|
||||||
fpu.round = (FPU_Round)((word >> 10) & 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE Bitu FPU_GET_TOP(void) {
|
|
||||||
return (fpu.sw & 0x3800)>>11;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void FPU_SET_TOP(Bitu val){
|
|
||||||
fpu.sw &= ~0x3800;
|
|
||||||
fpu.sw |= (val&7)<<11;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE void FPU_SET_C0(Bitu C){
|
|
||||||
fpu.sw &= ~0x0100;
|
|
||||||
if(C) fpu.sw |= 0x0100;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void FPU_SET_C1(Bitu C){
|
|
||||||
fpu.sw &= ~0x0200;
|
|
||||||
if(C) fpu.sw |= 0x0200;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void FPU_SET_C2(Bitu C){
|
|
||||||
fpu.sw &= ~0x0400;
|
|
||||||
if(C) fpu.sw |= 0x0400;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void FPU_SET_C3(Bitu C){
|
|
||||||
fpu.sw &= ~0x4000;
|
|
||||||
if(C) fpu.sw |= 0x4000;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2007 The DOSBox Team
|
* Copyright (C) 2002 The DOSBox Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -9,42 +9,36 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Library General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef DOSBOX_HARDWARE_H
|
#ifndef _HARDWARE_H_
|
||||||
#define DOSBOX_HARDWARE_H
|
#define _HARDWARE_H_
|
||||||
|
|
||||||
|
#include <programs.h>
|
||||||
|
#include <support.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
class Section;
|
typedef void (* HW_OutputHandler)(char * towrite);
|
||||||
enum OPL_Mode {
|
typedef void (* HW_InputHandler)(char * line);
|
||||||
OPL_none,OPL_cms,OPL_opl2,OPL_dualopl2,OPL_opl3
|
|
||||||
|
struct HWBlock {
|
||||||
|
char * dev_name; /* 8 characters max dev name */
|
||||||
|
char * full_name; /* 60 characters full name */
|
||||||
|
char * help;
|
||||||
|
HW_InputHandler get_input;
|
||||||
|
HW_OutputHandler show_status; /* Supplied with a string to display 50 chars of status info in */
|
||||||
|
HWBlock * next;
|
||||||
};
|
};
|
||||||
#define CAPTURE_WAVE 0x01
|
|
||||||
#define CAPTURE_OPL 0x02
|
|
||||||
#define CAPTURE_MIDI 0x04
|
|
||||||
#define CAPTURE_IMAGE 0x08
|
|
||||||
#define CAPTURE_VIDEO 0x10
|
|
||||||
|
|
||||||
extern Bitu CaptureState;
|
|
||||||
|
|
||||||
void OPL_Init(Section* sec,OPL_Mode mode);
|
void HW_Register(HWBlock * block);
|
||||||
void CMS_Init(Section* sec);
|
|
||||||
void OPL_ShutDown(Section* sec);
|
|
||||||
void CMS_ShutDown(Section* sec);
|
|
||||||
|
|
||||||
extern Bit8u adlib_commandreg;
|
|
||||||
FILE * OpenCaptureFile(const char * type,const char * ext);
|
|
||||||
|
|
||||||
void CAPTURE_AddWave(Bit32u freq, Bit32u len, Bit16s * data);
|
|
||||||
#define CAPTURE_FLAG_DBLW 0x1
|
|
||||||
#define CAPTURE_FLAG_DBLH 0x2
|
|
||||||
void CAPTURE_AddImage(Bitu width, Bitu height, Bitu bpp, Bitu pitch, Bitu flags, float fps, Bit8u * data, Bit8u * pal);
|
|
||||||
void CAPTURE_AddMidi(bool sysex, Bitu len, Bit8u * data);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2007 The DOSBox Team
|
* Copyright (C) 2002 The DOSBox Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -9,70 +9,40 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Library General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: inout.h,v 1.12 2009/04/25 16:25:03 harekiet Exp $ */
|
typedef Bit8u (IO_ReadHandler)(Bit32u port);
|
||||||
|
typedef void (IO_WriteHandler)(Bit32u port,Bit8u value);
|
||||||
|
|
||||||
#ifndef DOSBOX_INOUT_H
|
#define IO_MAX 1024
|
||||||
#define DOSBOX_INOUT_H
|
|
||||||
|
|
||||||
#define IO_MAX (64*1024+3)
|
struct IO_ReadBlock{
|
||||||
|
IO_ReadHandler * handler;
|
||||||
#define IO_MB 0x1
|
char * name;
|
||||||
#define IO_MW 0x2
|
|
||||||
#define IO_MD 0x4
|
|
||||||
#define IO_MA (IO_MB | IO_MW | IO_MD )
|
|
||||||
|
|
||||||
typedef Bitu IO_ReadHandler(Bitu port,Bitu iolen);
|
|
||||||
typedef void IO_WriteHandler(Bitu port,Bitu val,Bitu iolen);
|
|
||||||
|
|
||||||
extern IO_WriteHandler * io_writehandlers[3][IO_MAX];
|
|
||||||
extern IO_ReadHandler * io_readhandlers[3][IO_MAX];
|
|
||||||
|
|
||||||
void IO_RegisterReadHandler(Bitu port,IO_ReadHandler * handler,Bitu mask,Bitu range=1);
|
|
||||||
void IO_RegisterWriteHandler(Bitu port,IO_WriteHandler * handler,Bitu mask,Bitu range=1);
|
|
||||||
|
|
||||||
void IO_FreeReadHandler(Bitu port,Bitu mask,Bitu range=1);
|
|
||||||
void IO_FreeWriteHandler(Bitu port,Bitu mask,Bitu range=1);
|
|
||||||
|
|
||||||
void IO_WriteB(Bitu port,Bitu val);
|
|
||||||
void IO_WriteW(Bitu port,Bitu val);
|
|
||||||
void IO_WriteD(Bitu port,Bitu val);
|
|
||||||
|
|
||||||
Bitu IO_ReadB(Bitu port);
|
|
||||||
Bitu IO_ReadW(Bitu port);
|
|
||||||
Bitu IO_ReadD(Bitu port);
|
|
||||||
|
|
||||||
/* Classes to manage the IO objects created by the various devices.
|
|
||||||
* The io objects will remove itself on destruction.*/
|
|
||||||
class IO_Base{
|
|
||||||
protected:
|
|
||||||
bool installed;
|
|
||||||
Bitu m_port, m_mask,m_range;
|
|
||||||
public:
|
|
||||||
IO_Base():installed(false){};
|
|
||||||
};
|
|
||||||
class IO_ReadHandleObject: private IO_Base{
|
|
||||||
public:
|
|
||||||
void Install(Bitu port,IO_ReadHandler * handler,Bitu mask,Bitu range=1);
|
|
||||||
~IO_ReadHandleObject();
|
|
||||||
};
|
|
||||||
class IO_WriteHandleObject: private IO_Base{
|
|
||||||
public:
|
|
||||||
void Install(Bitu port,IO_WriteHandler * handler,Bitu mask,Bitu range=1);
|
|
||||||
~IO_WriteHandleObject();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static INLINE void IO_Write(Bitu port,Bit8u val) {
|
struct IO_WriteBlock{
|
||||||
IO_WriteB(port,val);
|
IO_WriteHandler * handler;
|
||||||
}
|
char * name;
|
||||||
static INLINE Bit8u IO_Read(Bitu port){
|
};
|
||||||
return (Bit8u)IO_ReadB(port);
|
|
||||||
}
|
extern IO_ReadBlock IO_ReadTable[IO_MAX];
|
||||||
|
extern IO_WriteBlock IO_WriteTable[IO_MAX];
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void IO_Write(Bitu num,Bit8u val);
|
||||||
|
Bit8u IO_Read(Bitu num);
|
||||||
|
|
||||||
|
void IO_RegisterReadHandler(Bit32u port,IO_ReadHandler * handler,char * name);
|
||||||
|
void IO_RegisterWriteHandler(Bit32u port,IO_WriteHandler * handler,char * name);
|
||||||
|
|
||||||
|
void IO_FreeReadHandler(Bit32u port);
|
||||||
|
void IO_FreeWriteHandler(Bit32u port);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
161
include/ipx.h
161
include/ipx.h
@ -1,161 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2002-2007 The DOSBox Team
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* $Id: ipx.h,v 1.12 2007/01/13 08:35:49 qbix79 Exp $ */
|
|
||||||
|
|
||||||
#ifndef DOSBOX_IPX_H
|
|
||||||
#define DOSBOX_IPX_H
|
|
||||||
|
|
||||||
// Uncomment this for a lot of debug messages:
|
|
||||||
//#define IPX_DEBUGMSG
|
|
||||||
|
|
||||||
#ifdef IPX_DEBUGMSG
|
|
||||||
#define LOG_IPX LOG_MSG
|
|
||||||
#else
|
|
||||||
#if defined (_MSC_VER)
|
|
||||||
#define LOG_IPX
|
|
||||||
#else
|
|
||||||
#define LOG_IPX(...)
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef DOSBOX_DOSBOX_H
|
|
||||||
#include "dosbox.h"
|
|
||||||
#endif
|
|
||||||
#ifndef DOSBOX_MEM_H
|
|
||||||
#include "mem.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// In Use Flag codes
|
|
||||||
#define USEFLAG_AVAILABLE 0x00
|
|
||||||
#define USEFLAG_AESTEMP 0xe0
|
|
||||||
#define USEFLAG_IPXCRIT 0xf8
|
|
||||||
#define USEFLAG_SPXLISTEN 0xf9
|
|
||||||
#define USEFLAG_PROCESSING 0xfa
|
|
||||||
#define USEFLAG_HOLDING 0xfb
|
|
||||||
#define USEFLAG_AESWAITING 0xfc
|
|
||||||
#define USEFLAG_AESCOUNT 0xfd
|
|
||||||
#define USEFLAG_LISTENING 0xfe
|
|
||||||
#define USEFLAG_SENDING 0xff
|
|
||||||
|
|
||||||
// Completion codes
|
|
||||||
#define COMP_SUCCESS 0x00
|
|
||||||
#define COMP_REMOTETERM 0xec
|
|
||||||
#define COMP_DISCONNECT 0xed
|
|
||||||
#define COMP_INVALIDID 0xee
|
|
||||||
#define COMP_SPXTABLEFULL 0xef
|
|
||||||
#define COMP_EVENTNOTCANCELED 0xf9
|
|
||||||
#define COMP_NOCONNECTION 0xfa
|
|
||||||
#define COMP_CANCELLED 0xfc
|
|
||||||
#define COMP_MALFORMED 0xfd
|
|
||||||
#define COMP_UNDELIVERABLE 0xfe
|
|
||||||
#define COMP_HARDWAREERROR 0xff
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma pack(1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// For Uint8 type
|
|
||||||
#include "SDL_net.h"
|
|
||||||
|
|
||||||
struct PackedIP {
|
|
||||||
Uint32 host;
|
|
||||||
Uint16 port;
|
|
||||||
} GCC_ATTRIBUTE(packed);
|
|
||||||
|
|
||||||
struct nodeType {
|
|
||||||
Uint8 node[6];
|
|
||||||
} GCC_ATTRIBUTE(packed) ;
|
|
||||||
|
|
||||||
struct IPXHeader {
|
|
||||||
Uint8 checkSum[2];
|
|
||||||
Uint8 length[2];
|
|
||||||
Uint8 transControl; // Transport control
|
|
||||||
Uint8 pType; // Packet type
|
|
||||||
|
|
||||||
struct transport {
|
|
||||||
Uint8 network[4];
|
|
||||||
union addrtype {
|
|
||||||
nodeType byNode;
|
|
||||||
PackedIP byIP ;
|
|
||||||
} GCC_ATTRIBUTE(packed) addr;
|
|
||||||
Uint8 socket[2];
|
|
||||||
} dest, src;
|
|
||||||
} GCC_ATTRIBUTE(packed);
|
|
||||||
|
|
||||||
struct fragmentDescriptor {
|
|
||||||
Bit16u offset;
|
|
||||||
Bit16u segment;
|
|
||||||
Bit16u size;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define IPXBUFFERSIZE 1424
|
|
||||||
|
|
||||||
class ECBClass {
|
|
||||||
public:
|
|
||||||
RealPt ECBAddr;
|
|
||||||
bool isInESRList;
|
|
||||||
ECBClass *prevECB; // Linked List
|
|
||||||
ECBClass *nextECB;
|
|
||||||
|
|
||||||
Bit8u iuflag; // Need to save data since we are not always in
|
|
||||||
Bit16u mysocket; // real mode
|
|
||||||
|
|
||||||
Bit8u* databuffer; // received data is stored here until we get called
|
|
||||||
Bitu buflen; // by Interrupt
|
|
||||||
|
|
||||||
#ifdef IPX_DEBUGMSG
|
|
||||||
Bitu SerialNumber;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ECBClass(Bit16u segment, Bit16u offset);
|
|
||||||
Bit16u getSocket(void);
|
|
||||||
|
|
||||||
Bit8u getInUseFlag(void);
|
|
||||||
|
|
||||||
void setInUseFlag(Bit8u flagval);
|
|
||||||
|
|
||||||
void setCompletionFlag(Bit8u flagval);
|
|
||||||
|
|
||||||
Bit16u getFragCount(void);
|
|
||||||
|
|
||||||
bool writeData();
|
|
||||||
void writeDataBuffer(Bit8u* buffer, Bit16u length);
|
|
||||||
|
|
||||||
void getFragDesc(Bit16u descNum, fragmentDescriptor *fragDesc);
|
|
||||||
RealPt getESRAddr(void);
|
|
||||||
|
|
||||||
void NotifyESR(void);
|
|
||||||
|
|
||||||
void setImmAddress(Bit8u *immAddr);
|
|
||||||
void getImmAddress(Bit8u* immAddr);
|
|
||||||
|
|
||||||
~ECBClass();
|
|
||||||
};
|
|
||||||
|
|
||||||
// The following routines may not be needed on all systems. On my build of SDL the IPaddress structure is 8 octects
|
|
||||||
// and therefore screws up my IPXheader structure since it needs to be packed.
|
|
||||||
|
|
||||||
void UnpackIP(PackedIP ipPack, IPaddress * ipAddr);
|
|
||||||
void PackIP(IPaddress ipAddr, PackedIP *ipPack);
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma pack()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,48 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2002-2007 The DOSBox Team
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef DOSBOX_IPXSERVER_H_
|
|
||||||
#define DOSBOX_IPXSERVER_H_
|
|
||||||
|
|
||||||
#if C_IPX
|
|
||||||
|
|
||||||
#include "SDL_net.h"
|
|
||||||
|
|
||||||
struct packetBuffer {
|
|
||||||
Bit8u buffer[1024];
|
|
||||||
Bit16s packetSize; // Packet size remaining in read
|
|
||||||
Bit16s packetRead; // Bytes read of total packet
|
|
||||||
bool inPacket; // In packet reception flag
|
|
||||||
bool connected; // Connected flag
|
|
||||||
bool waitsize;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define SOCKETTABLESIZE 16
|
|
||||||
#define CONVIP(hostvar) hostvar & 0xff, (hostvar >> 8) & 0xff, (hostvar >> 16) & 0xff, (hostvar >> 24) & 0xff
|
|
||||||
#define CONVIPX(hostvar) hostvar[0], hostvar[1], hostvar[2], hostvar[3], hostvar[4], hostvar[5]
|
|
||||||
|
|
||||||
|
|
||||||
void IPX_StopServer();
|
|
||||||
bool IPX_StartServer(Bit16u portnum);
|
|
||||||
bool IPX_isConnectedToServer(Bits tableNum, IPaddress ** ptrAddr);
|
|
||||||
|
|
||||||
Bit8u packetCRC(Bit8u *buffer, Bit16u bufSize);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2007 The DOSBox Team
|
* Copyright (C) 2002 The DOSBox Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -9,16 +9,13 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Library General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: joystick.h,v 1.12 2007/08/12 10:23:35 c2woody Exp $ */
|
|
||||||
#ifndef DOSBOX_JOYSTICK_H
|
|
||||||
#define DOSBOX_JOYSTICK_H
|
|
||||||
void JOYSTICK_Enable(Bitu which,bool enabled);
|
void JOYSTICK_Enable(Bitu which,bool enabled);
|
||||||
|
|
||||||
void JOYSTICK_Button(Bitu which,Bitu num,bool pressed);
|
void JOYSTICK_Button(Bitu which,Bitu num,bool pressed);
|
||||||
@ -26,25 +23,3 @@ void JOYSTICK_Button(Bitu which,Bitu num,bool pressed);
|
|||||||
void JOYSTICK_Move_X(Bitu which,float x);
|
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);
|
|
||||||
|
|
||||||
enum JoystickType {
|
|
||||||
JOY_NONE,
|
|
||||||
JOY_AUTO,
|
|
||||||
JOY_2AXIS,
|
|
||||||
JOY_4AXIS,
|
|
||||||
JOY_4AXIS_2,
|
|
||||||
JOY_FCS,
|
|
||||||
JOY_CH
|
|
||||||
};
|
|
||||||
|
|
||||||
extern JoystickType joytype;
|
|
||||||
extern bool button_wrapping_enabled;
|
|
||||||
#endif
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2007 The DOSBox Team
|
* Copyright (C) 2002 The DOSBox Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -9,18 +9,24 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Library General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef DOSBOX_KEYBOARD_H
|
typedef void(KEYBOARD_EventHandler)(void);
|
||||||
#define DOSBOX_KEYBOARD_H
|
void KEYBOARD_AddCode(Bit8u code);
|
||||||
|
void KEYBOARD_AddKey(Bitu keytype,bool pressed);
|
||||||
|
void KEYBOARD_AddEvent(Bitu keytype,Bitu state,KEYBOARD_EventHandler * handler);
|
||||||
|
|
||||||
enum KBD_KEYS {
|
|
||||||
KBD_NONE,
|
#define ALT_PRESSED 0x1
|
||||||
|
#define CTRL_PRESSED 0x2
|
||||||
|
#define SHIFT_PRESSED 0x4
|
||||||
|
|
||||||
|
enum {
|
||||||
KBD_1, KBD_2, KBD_3, KBD_4, KBD_5, KBD_6, KBD_7, KBD_8, KBD_9, KBD_0,
|
KBD_1, KBD_2, KBD_3, KBD_4, KBD_5, KBD_6, KBD_7, KBD_8, KBD_9, KBD_0,
|
||||||
KBD_q, KBD_w, KBD_e, KBD_r, KBD_t, KBD_y, KBD_u, KBD_i, KBD_o, KBD_p,
|
KBD_q, KBD_w, KBD_e, KBD_r, KBD_t, KBD_y, KBD_u, KBD_i, KBD_o, KBD_p,
|
||||||
KBD_a, KBD_s, KBD_d, KBD_f, KBD_g, KBD_h, KBD_j, KBD_k, KBD_l, KBD_z,
|
KBD_a, KBD_s, KBD_d, KBD_f, KBD_g, KBD_h, KBD_j, KBD_k, KBD_l, KBD_z,
|
||||||
@ -34,20 +40,15 @@ enum KBD_KEYS {
|
|||||||
KBD_capslock,KBD_scrolllock,KBD_numlock,
|
KBD_capslock,KBD_scrolllock,KBD_numlock,
|
||||||
|
|
||||||
KBD_grave,KBD_minus,KBD_equals,KBD_backslash,KBD_leftbracket,KBD_rightbracket,
|
KBD_grave,KBD_minus,KBD_equals,KBD_backslash,KBD_leftbracket,KBD_rightbracket,
|
||||||
KBD_semicolon,KBD_quote,KBD_period,KBD_comma,KBD_slash,KBD_extra_lt_gt,
|
KBD_semicolon,KBD_quote,KBD_period,KBD_comma,KBD_slash,
|
||||||
|
|
||||||
KBD_printscreen,KBD_pause,
|
|
||||||
KBD_insert,KBD_home,KBD_pageup,KBD_delete,KBD_end,KBD_pagedown,
|
KBD_insert,KBD_home,KBD_pageup,KBD_delete,KBD_end,KBD_pagedown,
|
||||||
KBD_left,KBD_up,KBD_down,KBD_right,
|
KBD_left,KBD_up,KBD_down,KBD_right,
|
||||||
|
|
||||||
KBD_kp1,KBD_kp2,KBD_kp3,KBD_kp4,KBD_kp5,KBD_kp6,KBD_kp7,KBD_kp8,KBD_kp9,KBD_kp0,
|
KBD_kp1,KBD_kp2,KBD_kp3,KBD_kp4,KBD_kp5,KBD_kp6,KBD_kp7,KBD_kp8,KBD_kp9,KBD_kp0,
|
||||||
KBD_kpdivide,KBD_kpmultiply,KBD_kpminus,KBD_kpplus,KBD_kpenter,KBD_kpperiod,
|
KBD_kpslash,KBD_kpmultiply,KBD_kpminus,KBD_kpplus,KBD_kpenter,KBD_kpperiod,
|
||||||
|
|
||||||
|
|
||||||
KBD_LAST
|
KBD_LAST
|
||||||
};
|
};
|
||||||
|
|
||||||
void KEYBOARD_ClrBuffer(void);
|
|
||||||
void KEYBOARD_AddKey(KBD_KEYS keytype,bool pressed);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
@ -1,67 +0,0 @@
|
|||||||
#ifndef DOSBOX_LOGGING_H
|
|
||||||
#define DOSBOX_LOGGING_H
|
|
||||||
enum LOG_TYPES {
|
|
||||||
LOG_ALL,
|
|
||||||
LOG_VGA, LOG_VGAGFX,LOG_VGAMISC,LOG_INT10,
|
|
||||||
LOG_SB,LOG_DMACONTROL,
|
|
||||||
LOG_FPU,LOG_CPU,LOG_PAGING,
|
|
||||||
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_IO,
|
|
||||||
LOG_MAX
|
|
||||||
};
|
|
||||||
|
|
||||||
enum LOG_SEVERITIES {
|
|
||||||
LOG_NORMAL,
|
|
||||||
LOG_WARN,
|
|
||||||
LOG_ERROR
|
|
||||||
};
|
|
||||||
|
|
||||||
#if C_DEBUG
|
|
||||||
class LOG
|
|
||||||
{
|
|
||||||
LOG_TYPES d_type;
|
|
||||||
LOG_SEVERITIES d_severity;
|
|
||||||
public:
|
|
||||||
|
|
||||||
LOG (LOG_TYPES type , LOG_SEVERITIES severity):
|
|
||||||
d_type(type),
|
|
||||||
d_severity(severity)
|
|
||||||
{}
|
|
||||||
void operator() (char const* buf, ...) GCC_ATTRIBUTE(__format__(__printf__, 2, 3)); //../src/debug/debug_gui.cpp
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
void DEBUG_ShowMsg(char const* format,...) GCC_ATTRIBUTE(__format__(__printf__, 1, 2));
|
|
||||||
#define LOG_MSG DEBUG_ShowMsg
|
|
||||||
|
|
||||||
#else //C_DEBUG
|
|
||||||
|
|
||||||
struct LOG
|
|
||||||
{
|
|
||||||
LOG(LOG_TYPES , LOG_SEVERITIES ) { }
|
|
||||||
void operator()(char const* ) { }
|
|
||||||
void operator()(char const* , double ) { }
|
|
||||||
void operator()(char const* , double , double ) { }
|
|
||||||
void operator()(char const* , double , double , double ) { }
|
|
||||||
void operator()(char const* , double , double , double , double ) { }
|
|
||||||
void operator()(char const* , double , double , double , double , double ) { }
|
|
||||||
|
|
||||||
void operator()(char const* , char const* ) { }
|
|
||||||
void operator()(char const* , char const* , double ) { }
|
|
||||||
void operator()(char const* , char const* , double ,double ) { }
|
|
||||||
void operator()(char const* , double , char const* ) { }
|
|
||||||
void operator()(char const* , double , double, char const* ) { }
|
|
||||||
void operator()(char const* , char const*, char const*) { }
|
|
||||||
|
|
||||||
|
|
||||||
}; //add missing operators to here
|
|
||||||
//try to avoid anything smaller than bit32...
|
|
||||||
void GFX_ShowMsg(char const* format,...) GCC_ATTRIBUTE(__format__(__printf__, 1, 2));
|
|
||||||
#define LOG_MSG GFX_ShowMsg
|
|
||||||
|
|
||||||
#endif //C_DEBUG
|
|
||||||
|
|
||||||
|
|
||||||
#endif //DOSBOX_LOGGING_H
|
|
@ -1,39 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2002-2007 The DOSBox Team
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef DOSBOX_MAPPER_H
|
|
||||||
#define DOSBOX_MAPPER_H
|
|
||||||
|
|
||||||
enum MapKeys {
|
|
||||||
MK_f1,MK_f2,MK_f3,MK_f4,MK_f5,MK_f6,MK_f7,MK_f8,MK_f9,MK_f10,MK_f11,MK_f12,
|
|
||||||
MK_return,MK_kpminus,MK_scrolllock,MK_printscreen,MK_pause
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef void (MAPPER_Handler)(bool pressed);
|
|
||||||
void MAPPER_AddHandler(MAPPER_Handler * handler,MapKeys key,Bitu mods,char const * const eventname,char const * const buttonname);
|
|
||||||
void MAPPER_Init(void);
|
|
||||||
void MAPPER_StartUp(Section * sec);
|
|
||||||
void MAPPER_Run(bool pressed);
|
|
||||||
void MAPPER_LosingFocus(void);
|
|
||||||
|
|
||||||
|
|
||||||
#define MMOD1 0x1
|
|
||||||
#define MMOD2 0x2
|
|
||||||
|
|
||||||
#endif
|
|
247
include/mem.h
247
include/mem.h
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2007 The DOSBox Team
|
* Copyright (C) 2002 The DOSBox Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -9,211 +9,200 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Library General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef DOSBOX_MEM_H
|
#if !defined __MEM_H
|
||||||
#define DOSBOX_MEM_H
|
#define __MEM_H
|
||||||
|
#include <dosbox.h>
|
||||||
|
|
||||||
#ifndef DOSBOX_DOSBOX_H
|
enum { MEMORY_HANDLER=1,MEMORY_RELOCATE=2};
|
||||||
#include "dosbox.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
#define bmemcpy(mem1,mem2,size) memcpy((void *)mem1,(void *)mem2,size)
|
||||||
|
|
||||||
|
typedef Bit8u (MEMORY_ReadHandler)(Bit32u start);
|
||||||
|
typedef void (MEMORY_WriteHandler)(Bit32u start,Bit8u val);
|
||||||
|
|
||||||
|
typedef Bit32u PhysOff;
|
||||||
typedef Bit32u PhysPt;
|
typedef Bit32u PhysPt;
|
||||||
|
typedef Bit8u * HostOff;
|
||||||
typedef Bit8u * HostPt;
|
typedef Bit8u * HostPt;
|
||||||
typedef Bit32u RealPt;
|
typedef Bit32u RealPt;
|
||||||
|
|
||||||
typedef Bit32s MemHandle;
|
struct PageEntry {
|
||||||
|
Bit8u type;
|
||||||
|
PhysOff base; /* Used to calculate relative offset */
|
||||||
|
struct {
|
||||||
|
MEMORY_WriteHandler * write;
|
||||||
|
MEMORY_ReadHandler * read;
|
||||||
|
} handler;
|
||||||
|
HostOff relocate; /* This points to host machine address */
|
||||||
|
};
|
||||||
|
|
||||||
#define MEM_PAGESIZE 4096
|
struct EMM_Handle {
|
||||||
|
Bit16u next;
|
||||||
|
Bit16u size; /* Size in pages */
|
||||||
|
PhysOff phys_base;
|
||||||
|
HostOff host_base;
|
||||||
|
bool active;
|
||||||
|
bool free;
|
||||||
|
};
|
||||||
|
|
||||||
extern HostPt MemBase;
|
INLINE Bit16u PAGES(Bit32u bytes) {
|
||||||
HostPt GetMemBase(void);
|
if ((bytes & 4095) == 0) return (Bit16u)(bytes>>12);
|
||||||
|
return (Bit16u)(1+(bytes>>12));
|
||||||
|
}
|
||||||
|
|
||||||
bool MEM_A20_Enabled(void);
|
extern Bit8u * memory;
|
||||||
void MEM_A20_Enable(bool enable);
|
extern EMM_Handle EMM_Handles[];
|
||||||
|
extern PageEntry * PageEntries[]; /* Number of pages */
|
||||||
|
|
||||||
/* Memory management / EMS mapping */
|
bool MEMORY_TestSpecial(PhysOff off);
|
||||||
HostPt MEM_GetBlockPage(void);
|
void MEMORY_SetupHandler(Bit32u page,Bit32u extra,PageEntry * handler);
|
||||||
Bitu MEM_FreeTotal(void); //Free 4 kb pages
|
void MEMORY_ResetHandler(Bit32u page,Bit32u pages);
|
||||||
Bitu MEM_FreeLargest(void); //Largest free 4 kb pages block
|
|
||||||
Bitu MEM_TotalPages(void); //Total amount of 4 kb pages
|
|
||||||
Bitu MEM_AllocatedPages(MemHandle handle); // amount of allocated pages of handle
|
void EMM_GetFree(Bit16u * maxblock,Bit16u * total);
|
||||||
MemHandle MEM_AllocatePages(Bitu pages,bool sequence);
|
void EMM_Allocate(Bit16u size,Bit16u * handle);
|
||||||
MemHandle MEM_GetNextFreePage(void);
|
void EMM_Free(Bit16u handle);
|
||||||
PhysPt MEM_AllocatePage(void);
|
|
||||||
void MEM_ReleasePages(MemHandle handle);
|
|
||||||
bool MEM_ReAllocatePages(MemHandle & handle,Bitu pages,bool sequence);
|
|
||||||
|
|
||||||
MemHandle MEM_NextHandle(MemHandle handle);
|
|
||||||
MemHandle MEM_NextHandleAt(MemHandle handle,Bitu where);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The folowing six functions are used everywhere in the end so these should be changed for
|
The folowing six functions are used everywhere in the end so these should be changed for
|
||||||
Working on big or little endian machines
|
Working on big or little endian machines
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY)
|
|
||||||
|
|
||||||
static INLINE Bit8u host_readb(HostPt off) {
|
INLINE Bit8u readb(HostOff off) {
|
||||||
return off[0];
|
|
||||||
}
|
|
||||||
static INLINE Bit16u host_readw(HostPt off) {
|
|
||||||
return off[0] | (off[1] << 8);
|
|
||||||
}
|
|
||||||
static INLINE Bit32u host_readd(HostPt off) {
|
|
||||||
return off[0] | (off[1] << 8) | (off[2] << 16) | (off[3] << 24);
|
|
||||||
}
|
|
||||||
static INLINE void host_writeb(HostPt off,Bit8u val) {
|
|
||||||
off[0]=val;
|
|
||||||
}
|
|
||||||
static INLINE void host_writew(HostPt off,Bit16u val) {
|
|
||||||
off[0]=(Bit8u)(val);
|
|
||||||
off[1]=(Bit8u)(val >> 8);
|
|
||||||
}
|
|
||||||
static INLINE void host_writed(HostPt off,Bit32u val) {
|
|
||||||
off[0]=(Bit8u)(val);
|
|
||||||
off[1]=(Bit8u)(val >> 8);
|
|
||||||
off[2]=(Bit8u)(val >> 16);
|
|
||||||
off[3]=(Bit8u)(val >> 24);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
static INLINE Bit8u host_readb(HostPt off) {
|
|
||||||
return *(Bit8u *)off;
|
return *(Bit8u *)off;
|
||||||
}
|
};
|
||||||
static INLINE Bit16u host_readw(HostPt off) {
|
INLINE Bit16u readw(HostOff off) {
|
||||||
return *(Bit16u *)off;
|
return *(Bit16u *)off;
|
||||||
}
|
};
|
||||||
static INLINE Bit32u host_readd(HostPt off) {
|
INLINE Bit32u readd(HostOff off) {
|
||||||
return *(Bit32u *)off;
|
return *(Bit32u *)off;
|
||||||
}
|
};
|
||||||
static INLINE void host_writeb(HostPt off,Bit8u val) {
|
INLINE void writeb(HostOff off,Bit8u val) {
|
||||||
*(Bit8u *)(off)=val;
|
*(Bit8u *)(off)=val;
|
||||||
}
|
};
|
||||||
static INLINE void host_writew(HostPt off,Bit16u val) {
|
INLINE void writew(HostOff off,Bit16u val) {
|
||||||
*(Bit16u *)(off)=val;
|
*(Bit16u *)(off)=val;
|
||||||
}
|
};
|
||||||
static INLINE void host_writed(HostPt off,Bit32u val) {
|
INLINE void writed(HostOff off,Bit32u val) {
|
||||||
*(Bit32u *)(off)=val;
|
*(Bit32u *)(off)=val;
|
||||||
}
|
};
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE void var_write(Bit8u * var, Bit8u val) {
|
|
||||||
host_writeb((HostPt)var, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void var_write(Bit16u * var, Bit16u val) {
|
|
||||||
host_writew((HostPt)var, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void var_write(Bit32u * var, Bit32u val) {
|
|
||||||
host_writed((HostPt)var, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* The Folowing six functions are slower but they recognize the paged memory system */
|
/* The Folowing six functions are slower but they recognize the paged memory system */
|
||||||
|
//TODO maybe make em inline to go a bit faster
|
||||||
|
|
||||||
Bit8u mem_readb(PhysPt pt);
|
Bit8u mem_readb(PhysOff off);
|
||||||
Bit16u mem_readw(PhysPt pt);
|
Bit16u mem_readw(PhysOff off);
|
||||||
Bit32u mem_readd(PhysPt pt);
|
Bit32u mem_readd(PhysOff off);
|
||||||
|
|
||||||
void mem_writeb(PhysPt pt,Bit8u val);
|
void mem_writeb(PhysOff off,Bit8u val);
|
||||||
void mem_writew(PhysPt pt,Bit16u val);
|
void mem_writew(PhysOff off,Bit16u val);
|
||||||
void mem_writed(PhysPt pt,Bit32u val);
|
void mem_writed(PhysOff off,Bit32u val);
|
||||||
|
|
||||||
static INLINE void phys_writeb(PhysPt addr,Bit8u val) {
|
|
||||||
host_writeb(MemBase+addr,val);
|
|
||||||
}
|
|
||||||
static INLINE void phys_writew(PhysPt addr,Bit16u val){
|
|
||||||
host_writew(MemBase+addr,val);
|
|
||||||
}
|
|
||||||
static INLINE void phys_writed(PhysPt addr,Bit32u val){
|
|
||||||
host_writed(MemBase+addr,val);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE Bit8u phys_readb(PhysPt addr) {
|
|
||||||
return host_readb(MemBase+addr);
|
|
||||||
}
|
|
||||||
static INLINE Bit16u phys_readw(PhysPt addr){
|
|
||||||
return host_readw(MemBase+addr);
|
|
||||||
}
|
|
||||||
static INLINE Bit32u phys_readd(PhysPt addr){
|
|
||||||
return host_readd(MemBase+addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* These don't check for alignment, better be sure it's correct */
|
|
||||||
|
|
||||||
void MEM_BlockWrite(PhysPt pt,void const * const data,Bitu size);
|
|
||||||
void MEM_BlockRead(PhysPt pt,void * data,Bitu size);
|
|
||||||
void MEM_BlockCopy(PhysPt dest,PhysPt src,Bitu size);
|
|
||||||
void MEM_StrCopy(PhysPt pt,char * data,Bitu size);
|
|
||||||
|
|
||||||
void mem_memcpy(PhysPt dest,PhysPt src,Bitu size);
|
void MEM_BlockWrite(PhysOff off,void * data,Bitu size);
|
||||||
Bitu mem_strlen(PhysPt pt);
|
void MEM_BlockRead(PhysOff off,void * data,Bitu size);
|
||||||
void mem_strcpy(PhysPt dest,PhysPt src);
|
void MEM_BlockCopy(PhysOff dest,PhysOff src,Bitu size);
|
||||||
|
void MEM_StrCopy(PhysOff off,char * data,Bitu size);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* The folowing functions are all shortcuts to the above functions using physical addressing */
|
/* The folowing functions are all shortcuts to the above functions using physical addressing */
|
||||||
|
|
||||||
static INLINE Bit8u real_readb(Bit16u seg,Bit16u off) {
|
INLINE HostOff real_off(Bit16u seg,Bit32u off) {
|
||||||
|
return memory+(seg<<4)+off;
|
||||||
|
};
|
||||||
|
|
||||||
|
INLINE HostOff real_host(Bit16u seg,Bit32u off) {
|
||||||
|
return memory+(seg<<4)+off;
|
||||||
|
};
|
||||||
|
INLINE PhysOff real_phys(Bit16u seg,Bit32u off) {
|
||||||
|
return (seg<<4)+off;
|
||||||
|
};
|
||||||
|
|
||||||
|
INLINE Bit8u real_readb(Bit16u seg,Bit16u off) {
|
||||||
return mem_readb((seg<<4)+off);
|
return mem_readb((seg<<4)+off);
|
||||||
}
|
}
|
||||||
static INLINE Bit16u real_readw(Bit16u seg,Bit16u off) {
|
INLINE Bit16u real_readw(Bit16u seg,Bit16u off) {
|
||||||
return mem_readw((seg<<4)+off);
|
return mem_readw((seg<<4)+off);
|
||||||
}
|
}
|
||||||
static INLINE Bit32u real_readd(Bit16u seg,Bit16u off) {
|
INLINE Bit32u real_readd(Bit16u seg,Bit16u off) {
|
||||||
return mem_readd((seg<<4)+off);
|
return mem_readd((seg<<4)+off);
|
||||||
}
|
}
|
||||||
|
//#define real_readb(seg,off) mem_readb(((seg)<<4)+(off))
|
||||||
|
//#define real_readw(seg,off) mem_readw(((seg)<<4)+(off))
|
||||||
|
//#define real_readd(seg,off) mem_readd(((seg)<<4)+(off))
|
||||||
|
|
||||||
static INLINE void real_writeb(Bit16u seg,Bit16u off,Bit8u val) {
|
INLINE void real_writeb(Bit16u seg,Bit16u off,Bit8u val) {
|
||||||
mem_writeb(((seg<<4)+off),val);
|
mem_writeb(((seg<<4)+off),val);
|
||||||
}
|
}
|
||||||
static INLINE void real_writew(Bit16u seg,Bit16u off,Bit16u val) {
|
INLINE void real_writew(Bit16u seg,Bit16u off,Bit16u val) {
|
||||||
mem_writew(((seg<<4)+off),val);
|
mem_writew(((seg<<4)+off),val);
|
||||||
}
|
}
|
||||||
static INLINE void real_writed(Bit16u seg,Bit16u off,Bit32u val) {
|
INLINE void real_writed(Bit16u seg,Bit16u off,Bit32u val) {
|
||||||
mem_writed(((seg<<4)+off),val);
|
mem_writed(((seg<<4)+off),val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static INLINE Bit16u RealSeg(RealPt pt) {
|
//#define real_writeb(seg,off,val) mem_writeb((((seg)<<4)+(off)),val)
|
||||||
|
//#define real_writew(seg,off,val) mem_writew((((seg)<<4)+(off)),val)
|
||||||
|
//#define real_writed(seg,off,val) mem_writed((((seg)<<4)+(off)),val)
|
||||||
|
|
||||||
|
inline Bit32u real_getvec(Bit8u num) {
|
||||||
|
return real_readd(0,(num<<2));
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
inline void real_setvec(Bit8u num,Bit32u addr) {
|
||||||
|
real_writed(0,(num<<2),addr);
|
||||||
|
};
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
INLINE Bit16u RealSeg(RealPt pt) {
|
||||||
return (Bit16u)(pt>>16);
|
return (Bit16u)(pt>>16);
|
||||||
}
|
}
|
||||||
|
|
||||||
static INLINE Bit16u RealOff(RealPt pt) {
|
INLINE Bit16u RealOff(RealPt pt) {
|
||||||
return (Bit16u)(pt&0xffff);
|
return (Bit16u)(pt&0xffff);
|
||||||
}
|
}
|
||||||
|
|
||||||
static INLINE PhysPt Real2Phys(RealPt pt) {
|
INLINE PhysPt Real2Phys(RealPt pt) {
|
||||||
return (RealSeg(pt)<<4) +RealOff(pt);
|
return (RealSeg(pt)<<4) +RealOff(pt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static INLINE PhysPt PhysMake(Bit16u seg,Bit16u off) {
|
|
||||||
return (seg<<4)+off;
|
INLINE HostPt Real2Host(RealPt pt) {
|
||||||
|
return memory+(RealSeg(pt)<<4) +RealOff(pt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static INLINE RealPt RealMake(Bit16u seg,Bit16u off) {
|
|
||||||
|
INLINE RealPt RealMake(Bit16u seg,Bit16u off) {
|
||||||
return (seg<<16)+off;
|
return (seg<<16)+off;
|
||||||
}
|
}
|
||||||
|
|
||||||
static INLINE void RealSetVec(Bit8u vec,RealPt pt) {
|
|
||||||
|
INLINE void RealSetVec(Bit8u vec,RealPt pt) {
|
||||||
mem_writed(vec<<2,pt);
|
mem_writed(vec<<2,pt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static INLINE void RealSetVec(Bit8u vec,RealPt pt,RealPt &old) {
|
INLINE RealPt RealGetVec(Bit8u vec) {
|
||||||
old = mem_readd(vec<<2);
|
|
||||||
mem_writed(vec<<2,pt);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE RealPt RealGetVec(Bit8u vec) {
|
|
||||||
return mem_readd(vec<<2);
|
return mem_readd(vec<<2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
106
include/mixer.h
106
include/mixer.h
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2009 The DOSBox Team
|
* Copyright (C) 2002 The DOSBox Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -9,106 +9,34 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Library General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: mixer.h,v 1.19 2009/04/28 21:48:24 harekiet Exp $ */
|
|
||||||
|
|
||||||
#ifndef DOSBOX_MIXER_H
|
|
||||||
#define DOSBOX_MIXER_H
|
|
||||||
|
|
||||||
#ifndef DOSBOX_DOSBOX_H
|
|
||||||
#include "dosbox.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef void (*MIXER_MixHandler)(Bit8u * sampdate,Bit32u len);
|
typedef void (*MIXER_MixHandler)(Bit8u * sampdate,Bit32u len);
|
||||||
typedef void (*MIXER_Handler)(Bitu len);
|
|
||||||
|
|
||||||
enum BlahModes {
|
#define MIXER_8MONO 0
|
||||||
MIXER_8MONO,MIXER_8STEREO,
|
#define MIXER_8STEREO 1
|
||||||
MIXER_16MONO,MIXER_16STEREO
|
#define MIXER_16MONO 2
|
||||||
};
|
#define MIXER_16STEREO 3
|
||||||
|
|
||||||
enum MixerModes {
|
|
||||||
M_8M,M_8S,
|
|
||||||
M_16M,M_16S
|
|
||||||
};
|
|
||||||
|
|
||||||
#define MIXER_BUFSIZE (16*1024)
|
|
||||||
#define MIXER_BUFMASK (MIXER_BUFSIZE-1)
|
|
||||||
extern Bit8u MixTemp[MIXER_BUFSIZE];
|
|
||||||
|
|
||||||
#define MAX_AUDIO ((1<<(16-1))-1)
|
#define MAX_AUDIO ((1<<(16-1))-1)
|
||||||
#define MIN_AUDIO -(1<<(16-1))
|
#define MIN_AUDIO -(1<<(16-1))
|
||||||
|
|
||||||
class MixerChannel {
|
|
||||||
public:
|
|
||||||
void SetVolume(float _left,float _right);
|
|
||||||
void SetScale( float f );
|
|
||||||
void UpdateVolume(void);
|
|
||||||
void SetFreq(Bitu _freq);
|
|
||||||
void Mix(Bitu _needed);
|
|
||||||
void AddSilence(void); //Fill up until needed
|
|
||||||
|
|
||||||
template<class Type,bool stereo,bool signeddata,bool nativeorder>
|
|
||||||
void AddSamples(Bitu len, const Type* data);
|
|
||||||
|
|
||||||
void AddSamples_m8(Bitu len, const Bit8u * data);
|
|
||||||
void AddSamples_s8(Bitu len, const Bit8u * data);
|
|
||||||
void AddSamples_m8s(Bitu len, const Bit8s * data);
|
|
||||||
void AddSamples_s8s(Bitu len, const Bit8s * data);
|
|
||||||
void AddSamples_m16(Bitu len, const Bit16s * data);
|
|
||||||
void AddSamples_s16(Bitu len, const Bit16s * data);
|
|
||||||
void AddSamples_m16u(Bitu len, const Bit16u * data);
|
|
||||||
void AddSamples_s16u(Bitu len, const Bit16u * data);
|
|
||||||
void AddSamples_m32(Bitu len, const Bit32s * data);
|
|
||||||
void AddSamples_s32(Bitu len, const Bit32s * data);
|
|
||||||
void AddSamples_m16_nonnative(Bitu len, const Bit16s * data);
|
|
||||||
void AddSamples_s16_nonnative(Bitu len, const Bit16s * data);
|
|
||||||
void AddSamples_m16u_nonnative(Bitu len, const Bit16u * data);
|
|
||||||
void AddSamples_s16u_nonnative(Bitu len, const Bit16u * data);
|
|
||||||
void AddSamples_m32_nonnative(Bitu len, const Bit32s * data);
|
|
||||||
void AddSamples_s32_nonnative(Bitu len, const Bit32s * data);
|
|
||||||
|
|
||||||
void AddStretched(Bitu len,Bit16s * data); //Strech block up into needed data
|
|
||||||
void FillUp(void);
|
|
||||||
void Enable(bool _yesno);
|
|
||||||
MIXER_Handler handler;
|
|
||||||
float volmain[2];
|
|
||||||
float scale;
|
|
||||||
Bit32s volmul[2];
|
|
||||||
Bitu freq_add,freq_index;
|
|
||||||
Bitu done,needed;
|
|
||||||
Bits last[2];
|
|
||||||
const char * name;
|
|
||||||
bool enabled;
|
|
||||||
MixerChannel * next;
|
|
||||||
};
|
|
||||||
|
|
||||||
MixerChannel * MIXER_AddChannel(MIXER_Handler handler,Bitu freq,const char * name);
|
|
||||||
MixerChannel * MIXER_FindChannel(const char * name);
|
|
||||||
/* Find the device you want to delete with findchannel "delchan gets deleted" */
|
|
||||||
void MIXER_DelChannel(MixerChannel* delchan);
|
|
||||||
|
|
||||||
/* Object to maintain a mixerchannel; As all objects it registers itself with create
|
|
||||||
* and removes itself when destroyed. */
|
|
||||||
class MixerObject{
|
|
||||||
private:
|
|
||||||
bool installed;
|
|
||||||
char m_name[32];
|
|
||||||
public:
|
|
||||||
MixerObject():installed(false){};
|
|
||||||
MixerChannel* Install(MIXER_Handler handler,Bitu freq,const char * name);
|
|
||||||
~MixerObject();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/* PC Speakers functions, tightly related to the timer functions */
|
struct MIXER_Channel;
|
||||||
void PCSPEAKER_SetCounter(Bitu cntr,Bitu mode);
|
|
||||||
void PCSPEAKER_SetType(Bitu mode);
|
|
||||||
|
MIXER_Channel * MIXER_AddChannel(MIXER_MixHandler handler,Bit32u freq,char * name);
|
||||||
|
void MIXER_SetVolume(MIXER_Channel * chan,Bit8u vol);
|
||||||
|
void MIXER_SetFreq(MIXER_Channel * chan,Bit32u freq);
|
||||||
|
void MIXER_SetMode(MIXER_Channel * chan,Bit8u mode);
|
||||||
|
void MIXER_Enable(MIXER_Channel * chan,bool enable);
|
||||||
|
|
||||||
|
void PCSPEAKER_Enable(bool enable);
|
||||||
|
void PCSPEAKER_SetFreq(Bit32u freq);
|
||||||
|
|
||||||
#endif
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2007 The DOSBox Team
|
* Copyright (C) 2002 The DOSBox Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -9,34 +9,20 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Library General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: mouse.h,v 1.14 2008/03/08 22:04:44 c2woody Exp $ */
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef DOSBOX_MOUSE_H
|
|
||||||
#define DOSBOX_MOUSE_H
|
|
||||||
|
|
||||||
|
|
||||||
void Mouse_ShowCursor(void);
|
void Mouse_ShowCursor(void);
|
||||||
void Mouse_HideCursor(void);
|
void Mouse_HideCursor(void);
|
||||||
|
|
||||||
bool Mouse_SetPS2State(bool use);
|
|
||||||
|
|
||||||
void Mouse_ChangePS2Callback(Bit16u pseg, Bit16u pofs);
|
void Mouse_CursorMoved(float x,float y);
|
||||||
|
|
||||||
|
|
||||||
void Mouse_CursorMoved(float xrel,float yrel,float x,float y,bool emulate);
|
|
||||||
void Mouse_CursorSet(float x,float y);
|
void Mouse_CursorSet(float x,float y);
|
||||||
void Mouse_ButtonPressed(Bit8u button);
|
void Mouse_ButtonPressed(Bit8u button);
|
||||||
void Mouse_ButtonReleased(Bit8u button);
|
void Mouse_ButtonReleased(Bit8u button);
|
||||||
|
|
||||||
void Mouse_AutoLock(bool enable);
|
|
||||||
void Mouse_NewVideoMode(void);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
366
include/paging.h
366
include/paging.h
@ -1,366 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2002-2008 The DOSBox Team
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* $Id: paging.h,v 1.32 2009/04/25 16:25:03 harekiet Exp $ */
|
|
||||||
|
|
||||||
#ifndef DOSBOX_PAGING_H
|
|
||||||
#define DOSBOX_PAGING_H
|
|
||||||
|
|
||||||
#ifndef DOSBOX_DOSBOX_H
|
|
||||||
#include "dosbox.h"
|
|
||||||
#endif
|
|
||||||
#ifndef DOSBOX_MEM_H
|
|
||||||
#include "mem.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// disable this to reduce the size of the TLB
|
|
||||||
// NOTE: does not work with the dynamic core (dynrec is fine)
|
|
||||||
#define USE_FULL_TLB
|
|
||||||
|
|
||||||
class PageDirectory;
|
|
||||||
|
|
||||||
#define MEM_PAGE_SIZE (4096)
|
|
||||||
#define XMS_START (0x110)
|
|
||||||
|
|
||||||
#if defined(USE_FULL_TLB)
|
|
||||||
#define TLB_SIZE (1024*1024)
|
|
||||||
#else
|
|
||||||
#define TLB_SIZE 65536 // This must a power of 2 and greater then LINK_START
|
|
||||||
#define BANK_SHIFT 28
|
|
||||||
#define BANK_MASK 0xffff // always the same as TLB_SIZE-1?
|
|
||||||
#define TLB_BANKS ((1024*1024/TLB_SIZE)-1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PFLAG_READABLE 0x1
|
|
||||||
#define PFLAG_WRITEABLE 0x2
|
|
||||||
#define PFLAG_HASROM 0x4
|
|
||||||
#define PFLAG_HASCODE 0x8 //Page contains dynamic code
|
|
||||||
#define PFLAG_NOCODE 0x10 //No dynamic code can be generated here
|
|
||||||
#define PFLAG_INIT 0x20 //No dynamic code can be generated here
|
|
||||||
|
|
||||||
#define LINK_START ((1024+64)/4) //Start right after the HMA
|
|
||||||
|
|
||||||
//Allow 128 mb of memory to be linked
|
|
||||||
#define PAGING_LINKS (128*1024/4)
|
|
||||||
|
|
||||||
class PageHandler {
|
|
||||||
public:
|
|
||||||
virtual ~PageHandler(void) { }
|
|
||||||
virtual Bitu readb(PhysPt addr);
|
|
||||||
virtual Bitu readw(PhysPt addr);
|
|
||||||
virtual Bitu readd(PhysPt addr);
|
|
||||||
virtual void writeb(PhysPt addr,Bitu val);
|
|
||||||
virtual void writew(PhysPt addr,Bitu val);
|
|
||||||
virtual void writed(PhysPt addr,Bitu val);
|
|
||||||
virtual HostPt GetHostReadPt(Bitu phys_page);
|
|
||||||
virtual HostPt GetHostWritePt(Bitu phys_page);
|
|
||||||
virtual bool readb_checked(PhysPt addr,Bit8u * val);
|
|
||||||
virtual bool readw_checked(PhysPt addr,Bit16u * val);
|
|
||||||
virtual bool readd_checked(PhysPt addr,Bit32u * val);
|
|
||||||
virtual bool writeb_checked(PhysPt addr,Bitu val);
|
|
||||||
virtual bool writew_checked(PhysPt addr,Bitu val);
|
|
||||||
virtual bool writed_checked(PhysPt addr,Bitu val);
|
|
||||||
Bitu flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Some other functions */
|
|
||||||
void PAGING_Enable(bool enabled);
|
|
||||||
bool PAGING_Enabled(void);
|
|
||||||
|
|
||||||
Bitu PAGING_GetDirBase(void);
|
|
||||||
void PAGING_SetDirBase(Bitu cr3);
|
|
||||||
void PAGING_InitTLB(void);
|
|
||||||
void PAGING_ClearTLB(void);
|
|
||||||
|
|
||||||
void PAGING_LinkPage(Bitu lin_page,Bitu phys_page);
|
|
||||||
void PAGING_LinkPage_ReadOnly(Bitu lin_page,Bitu phys_page);
|
|
||||||
void PAGING_UnlinkPages(Bitu lin_page,Bitu pages);
|
|
||||||
/* This maps the page directly, only use when paging is disabled */
|
|
||||||
void PAGING_MapPage(Bitu lin_page,Bitu phys_page);
|
|
||||||
bool PAGING_MakePhysPage(Bitu & page);
|
|
||||||
bool PAGING_ForcePageInit(Bitu lin_addr);
|
|
||||||
|
|
||||||
void MEM_SetLFB(Bitu page, Bitu pages, PageHandler *handler, PageHandler *mmiohandler);
|
|
||||||
void MEM_SetPageHandler(Bitu phys_page, Bitu pages, PageHandler * handler);
|
|
||||||
void MEM_ResetPageHandler(Bitu phys_page, Bitu pages);
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma pack (1)
|
|
||||||
#endif
|
|
||||||
struct X86_PageEntryBlock{
|
|
||||||
#ifdef WORDS_BIGENDIAN
|
|
||||||
Bit32u base:20;
|
|
||||||
Bit32u avl:3;
|
|
||||||
Bit32u g:1;
|
|
||||||
Bit32u pat:1;
|
|
||||||
Bit32u d:1;
|
|
||||||
Bit32u a:1;
|
|
||||||
Bit32u pcd:1;
|
|
||||||
Bit32u pwt:1;
|
|
||||||
Bit32u us:1;
|
|
||||||
Bit32u wr:1;
|
|
||||||
Bit32u p:1;
|
|
||||||
#else
|
|
||||||
Bit32u p:1;
|
|
||||||
Bit32u wr:1;
|
|
||||||
Bit32u us:1;
|
|
||||||
Bit32u pwt:1;
|
|
||||||
Bit32u pcd:1;
|
|
||||||
Bit32u a:1;
|
|
||||||
Bit32u d:1;
|
|
||||||
Bit32u pat:1;
|
|
||||||
Bit32u g:1;
|
|
||||||
Bit32u avl:3;
|
|
||||||
Bit32u base:20;
|
|
||||||
#endif
|
|
||||||
} GCC_ATTRIBUTE(packed);
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma pack ()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
union X86PageEntry {
|
|
||||||
Bit32u load;
|
|
||||||
X86_PageEntryBlock block;
|
|
||||||
};
|
|
||||||
|
|
||||||
#if !defined(USE_FULL_TLB)
|
|
||||||
typedef struct {
|
|
||||||
HostPt read;
|
|
||||||
HostPt write;
|
|
||||||
PageHandler * readhandler;
|
|
||||||
PageHandler * writehandler;
|
|
||||||
Bit32u phys_page;
|
|
||||||
} tlb_entry;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct PagingBlock {
|
|
||||||
Bitu cr3;
|
|
||||||
Bitu cr2;
|
|
||||||
struct {
|
|
||||||
Bitu page;
|
|
||||||
PhysPt addr;
|
|
||||||
} base;
|
|
||||||
#if defined(USE_FULL_TLB)
|
|
||||||
struct {
|
|
||||||
HostPt read[TLB_SIZE];
|
|
||||||
HostPt write[TLB_SIZE];
|
|
||||||
PageHandler * readhandler[TLB_SIZE];
|
|
||||||
PageHandler * writehandler[TLB_SIZE];
|
|
||||||
Bit32u phys_page[TLB_SIZE];
|
|
||||||
} tlb;
|
|
||||||
#else
|
|
||||||
tlb_entry tlbh[TLB_SIZE];
|
|
||||||
tlb_entry *tlbh_banks[TLB_BANKS];
|
|
||||||
#endif
|
|
||||||
struct {
|
|
||||||
Bitu used;
|
|
||||||
Bit32u entries[PAGING_LINKS];
|
|
||||||
} links;
|
|
||||||
Bit32u firstmb[LINK_START];
|
|
||||||
bool enabled;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern PagingBlock paging;
|
|
||||||
|
|
||||||
/* Some support functions */
|
|
||||||
|
|
||||||
PageHandler * MEM_GetPageHandler(Bitu phys_page);
|
|
||||||
|
|
||||||
|
|
||||||
/* Unaligned address handlers */
|
|
||||||
Bit16u mem_unalignedreadw(PhysPt address);
|
|
||||||
Bit32u mem_unalignedreadd(PhysPt address);
|
|
||||||
void mem_unalignedwritew(PhysPt address,Bit16u val);
|
|
||||||
void mem_unalignedwrited(PhysPt address,Bit32u val);
|
|
||||||
|
|
||||||
bool mem_unalignedreadw_checked(PhysPt address,Bit16u * val);
|
|
||||||
bool mem_unalignedreadd_checked(PhysPt address,Bit32u * val);
|
|
||||||
bool mem_unalignedwritew_checked(PhysPt address,Bit16u val);
|
|
||||||
bool mem_unalignedwrited_checked(PhysPt address,Bit32u val);
|
|
||||||
|
|
||||||
#if defined(USE_FULL_TLB)
|
|
||||||
|
|
||||||
static INLINE HostPt get_tlb_read(PhysPt address) {
|
|
||||||
return paging.tlb.read[address>>12];
|
|
||||||
}
|
|
||||||
static INLINE HostPt get_tlb_write(PhysPt address) {
|
|
||||||
return paging.tlb.write[address>>12];
|
|
||||||
}
|
|
||||||
static INLINE PageHandler* get_tlb_readhandler(PhysPt address) {
|
|
||||||
return paging.tlb.readhandler[address>>12];
|
|
||||||
}
|
|
||||||
static INLINE PageHandler* get_tlb_writehandler(PhysPt address) {
|
|
||||||
return paging.tlb.writehandler[address>>12];
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Use these helper functions to access linear addresses in readX/writeX functions */
|
|
||||||
static INLINE PhysPt PAGING_GetPhysicalPage(PhysPt linePage) {
|
|
||||||
return (paging.tlb.phys_page[linePage>>12]<<12);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE PhysPt PAGING_GetPhysicalAddress(PhysPt linAddr) {
|
|
||||||
return (paging.tlb.phys_page[linAddr>>12]<<12)|(linAddr&0xfff);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
void PAGING_InitTLBBank(tlb_entry **bank);
|
|
||||||
|
|
||||||
static INLINE tlb_entry *get_tlb_entry(PhysPt address) {
|
|
||||||
Bitu index=(address>>12);
|
|
||||||
if (TLB_BANKS && (index > TLB_SIZE)) {
|
|
||||||
Bitu bank=(address>>BANK_SHIFT) - 1;
|
|
||||||
if (!paging.tlbh_banks[bank])
|
|
||||||
PAGING_InitTLBBank(&paging.tlbh_banks[bank]);
|
|
||||||
return &paging.tlbh_banks[bank][index & BANK_MASK];
|
|
||||||
}
|
|
||||||
return &paging.tlbh[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE HostPt get_tlb_read(PhysPt address) {
|
|
||||||
return get_tlb_entry(address)->read;
|
|
||||||
}
|
|
||||||
static INLINE HostPt get_tlb_write(PhysPt address) {
|
|
||||||
return get_tlb_entry(address)->write;
|
|
||||||
}
|
|
||||||
static INLINE PageHandler* get_tlb_readhandler(PhysPt address) {
|
|
||||||
return get_tlb_entry(address)->readhandler;
|
|
||||||
}
|
|
||||||
static INLINE PageHandler* get_tlb_writehandler(PhysPt address) {
|
|
||||||
return get_tlb_entry(address)->writehandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Use these helper functions to access linear addresses in readX/writeX functions */
|
|
||||||
static INLINE PhysPt PAGING_GetPhysicalPage(PhysPt linePage) {
|
|
||||||
tlb_entry *entry = get_tlb_entry(linePage);
|
|
||||||
return (entry->phys_page<<12);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE PhysPt PAGING_GetPhysicalAddress(PhysPt linAddr) {
|
|
||||||
tlb_entry *entry = get_tlb_entry(linAddr);
|
|
||||||
return (entry->phys_page<<12)|(linAddr&0xfff);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Special inlined memory reading/writing */
|
|
||||||
|
|
||||||
static INLINE Bit8u mem_readb_inline(PhysPt address) {
|
|
||||||
HostPt tlb_addr=get_tlb_read(address);
|
|
||||||
if (tlb_addr) return host_readb(tlb_addr+address);
|
|
||||||
else return (Bit8u)(get_tlb_readhandler(address))->readb(address);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE Bit16u mem_readw_inline(PhysPt address) {
|
|
||||||
if ((address & 0xfff)<0xfff) {
|
|
||||||
HostPt tlb_addr=get_tlb_read(address);
|
|
||||||
if (tlb_addr) return host_readw(tlb_addr+address);
|
|
||||||
else return (Bit16u)(get_tlb_readhandler(address))->readw(address);
|
|
||||||
} else return mem_unalignedreadw(address);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE Bit32u mem_readd_inline(PhysPt address) {
|
|
||||||
if ((address & 0xfff)<0xffd) {
|
|
||||||
HostPt tlb_addr=get_tlb_read(address);
|
|
||||||
if (tlb_addr) return host_readd(tlb_addr+address);
|
|
||||||
else return (get_tlb_readhandler(address))->readd(address);
|
|
||||||
} else return mem_unalignedreadd(address);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void mem_writeb_inline(PhysPt address,Bit8u val) {
|
|
||||||
HostPt tlb_addr=get_tlb_write(address);
|
|
||||||
if (tlb_addr) host_writeb(tlb_addr+address,val);
|
|
||||||
else (get_tlb_writehandler(address))->writeb(address,val);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void mem_writew_inline(PhysPt address,Bit16u val) {
|
|
||||||
if ((address & 0xfff)<0xfff) {
|
|
||||||
HostPt tlb_addr=get_tlb_write(address);
|
|
||||||
if (tlb_addr) host_writew(tlb_addr+address,val);
|
|
||||||
else (get_tlb_writehandler(address))->writew(address,val);
|
|
||||||
} else mem_unalignedwritew(address,val);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void mem_writed_inline(PhysPt address,Bit32u val) {
|
|
||||||
if ((address & 0xfff)<0xffd) {
|
|
||||||
HostPt tlb_addr=get_tlb_write(address);
|
|
||||||
if (tlb_addr) host_writed(tlb_addr+address,val);
|
|
||||||
else (get_tlb_writehandler(address))->writed(address,val);
|
|
||||||
} else mem_unalignedwrited(address,val);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE bool mem_readb_checked(PhysPt address, Bit8u * val) {
|
|
||||||
HostPt tlb_addr=get_tlb_read(address);
|
|
||||||
if (tlb_addr) {
|
|
||||||
*val=host_readb(tlb_addr+address);
|
|
||||||
return false;
|
|
||||||
} else return (get_tlb_readhandler(address))->readb_checked(address, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE bool mem_readw_checked(PhysPt address, Bit16u * val) {
|
|
||||||
if ((address & 0xfff)<0xfff) {
|
|
||||||
HostPt tlb_addr=get_tlb_read(address);
|
|
||||||
if (tlb_addr) {
|
|
||||||
*val=host_readw(tlb_addr+address);
|
|
||||||
return false;
|
|
||||||
} else return (get_tlb_readhandler(address))->readw_checked(address, val);
|
|
||||||
} else return mem_unalignedreadw_checked(address, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE bool mem_readd_checked(PhysPt address, Bit32u * val) {
|
|
||||||
if ((address & 0xfff)<0xffd) {
|
|
||||||
HostPt tlb_addr=get_tlb_read(address);
|
|
||||||
if (tlb_addr) {
|
|
||||||
*val=host_readd(tlb_addr+address);
|
|
||||||
return false;
|
|
||||||
} else return (get_tlb_readhandler(address))->readd_checked(address, val);
|
|
||||||
} else return mem_unalignedreadd_checked(address, val);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE bool mem_writeb_checked(PhysPt address,Bit8u val) {
|
|
||||||
HostPt tlb_addr=get_tlb_write(address);
|
|
||||||
if (tlb_addr) {
|
|
||||||
host_writeb(tlb_addr+address,val);
|
|
||||||
return false;
|
|
||||||
} else return (get_tlb_writehandler(address))->writeb_checked(address,val);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE bool mem_writew_checked(PhysPt address,Bit16u val) {
|
|
||||||
if ((address & 0xfff)<0xfff) {
|
|
||||||
HostPt tlb_addr=get_tlb_write(address);
|
|
||||||
if (tlb_addr) {
|
|
||||||
host_writew(tlb_addr+address,val);
|
|
||||||
return false;
|
|
||||||
} else return (get_tlb_writehandler(address))->writew_checked(address,val);
|
|
||||||
} else return mem_unalignedwritew_checked(address,val);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE bool mem_writed_checked(PhysPt address,Bit32u val) {
|
|
||||||
if ((address & 0xfff)<0xffd) {
|
|
||||||
HostPt tlb_addr=get_tlb_write(address);
|
|
||||||
if (tlb_addr) {
|
|
||||||
host_writed(tlb_addr+address,val);
|
|
||||||
return false;
|
|
||||||
} else return (get_tlb_writehandler(address))->writed_checked(address,val);
|
|
||||||
} else return mem_unalignedwrited_checked(address,val);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2007 The DOSBox Team
|
* Copyright (C) 2002 The DOSBox Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -9,59 +9,36 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Library General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef DOSBOX_PIC_H
|
#ifndef __PIC_H
|
||||||
#define DOSBOX_PIC_H
|
#define __PIC_H
|
||||||
|
|
||||||
|
|
||||||
/* CPU Cycle Timing */
|
|
||||||
extern Bit32s CPU_Cycles;
|
|
||||||
extern Bit32s CPU_CycleLeft;
|
|
||||||
extern Bit32s CPU_CycleMax;
|
|
||||||
|
|
||||||
typedef void (PIC_EOIHandler) (void);
|
typedef void (PIC_EOIHandler) (void);
|
||||||
typedef void (* PIC_EventHandler)(Bitu val);
|
typedef void (PIC_Function)(void);
|
||||||
|
|
||||||
|
extern Bit32u PIC_IRQCheck;
|
||||||
|
|
||||||
#define PIC_MAXIRQ 15
|
void PIC_ActivateIRQ(Bit32u irq);
|
||||||
#define PIC_NOIRQ 0xFF
|
|
||||||
|
|
||||||
extern Bitu PIC_IRQCheck;
|
void PIC_DeActivateIRQ(Bit32u irq);
|
||||||
extern Bitu PIC_IRQActive;
|
|
||||||
extern Bitu PIC_Ticks;
|
|
||||||
|
|
||||||
static INLINE float PIC_TickIndex(void) {
|
|
||||||
return (CPU_CycleMax-CPU_CycleLeft-CPU_Cycles)/(float)CPU_CycleMax;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE Bits PIC_TickIndexND(void) {
|
|
||||||
return CPU_CycleMax-CPU_CycleLeft-CPU_Cycles;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE Bits PIC_MakeCycles(double amount) {
|
|
||||||
return (Bits)(CPU_CycleMax*amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE double PIC_FullIndex(void) {
|
|
||||||
return PIC_Ticks+(double)PIC_TickIndex();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PIC_ActivateIRQ(Bitu irq);
|
|
||||||
void PIC_DeActivateIRQ(Bitu irq);
|
|
||||||
|
|
||||||
void PIC_runIRQs(void);
|
void PIC_runIRQs(void);
|
||||||
bool PIC_RunQueue(void);
|
|
||||||
|
|
||||||
//Delay in milliseconds
|
void PIC_RegisterIRQ(Bit32u irq,PIC_EOIHandler handler,char * name);
|
||||||
void PIC_AddEvent(PIC_EventHandler handler,float delay,Bitu val=0);
|
void PIC_FreeIRQ(Bit32u irq);
|
||||||
void PIC_RemoveEvents(PIC_EventHandler handler);
|
|
||||||
void PIC_RemoveSpecificEvents(PIC_EventHandler handler, Bitu val);
|
bool PIC_IRQActive(Bit32u irq);
|
||||||
|
|
||||||
|
/* A Queued function should never queue itself again this will go horribly wrong */
|
||||||
|
void PIC_QueueFunction(PIC_Function * function);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void PIC_SetIRQMask(Bitu irq, bool masked);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2007 The DOSBox Team
|
* Copyright (C) 2002 The DOSBox Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -9,82 +9,50 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Library General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: programs.h,v 1.18 2009/03/11 20:18:37 qbix79 Exp $ */
|
#ifndef __PROGRAM_H
|
||||||
|
#define __PROGRAM_H
|
||||||
|
#include <dosbox.h>
|
||||||
|
#include <dos_inc.h>
|
||||||
|
|
||||||
#ifndef DOSBOX_PROGRAMS_H
|
|
||||||
#define DOSBOX_PROGRAMS_H
|
|
||||||
|
|
||||||
#ifndef DOSBOX_DOSBOX_H
|
char * MSG_Get(char * msg);
|
||||||
#include "dosbox.h"
|
|
||||||
#endif
|
|
||||||
#ifndef DOSBOX_DOS_INC_H
|
|
||||||
#include "dos_inc.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CH_LIST
|
struct PROGRAM_Info {
|
||||||
#define CH_LIST
|
Bit16u psp_seg;
|
||||||
#include <list>
|
PSP psp_copy;
|
||||||
#endif
|
char full_name[32]; //Enough space for programs only on the z:\ drive
|
||||||
|
char * cmd_line;
|
||||||
#ifndef CH_STRING
|
|
||||||
#define CH_STRING
|
|
||||||
#include <string>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class CommandLine {
|
|
||||||
public:
|
|
||||||
CommandLine(int argc,char const * const argv[]);
|
|
||||||
CommandLine(char const * const name,char const * const cmdline);
|
|
||||||
const char * GetFileName(){ return file_name.c_str();}
|
|
||||||
|
|
||||||
bool FindExist(char const * const name,bool remove=false);
|
|
||||||
bool FindHex(char const * const name,int & value,bool remove=false);
|
|
||||||
bool FindInt(char const * const name,int & value,bool remove=false);
|
|
||||||
bool FindString(char const * const name,std::string & value,bool remove=false);
|
|
||||||
bool FindCommand(unsigned int which,std::string & value);
|
|
||||||
bool FindStringBegin(char const * const begin,std::string & value, bool remove=false);
|
|
||||||
bool FindStringRemain(char const * const name,std::string & value);
|
|
||||||
bool GetStringRemain(std::string & value);
|
|
||||||
unsigned int GetCount(void);
|
|
||||||
void Shift(unsigned int amount=1);
|
|
||||||
Bit16u Get_arglength();
|
|
||||||
|
|
||||||
private:
|
|
||||||
typedef std::list<std::string>::iterator cmd_it;
|
|
||||||
std::list<std::string> cmds;
|
|
||||||
std::string file_name;
|
|
||||||
bool FindEntry(char const * const name,cmd_it & it,bool neednext=false);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef void (PROGRAMS_Main)(PROGRAM_Info * info);
|
||||||
|
void PROGRAMS_MakeFile(char * name,PROGRAMS_Main * main);
|
||||||
|
|
||||||
class Program {
|
class Program {
|
||||||
public:
|
public:
|
||||||
Program();
|
Program(PROGRAM_Info * program_info);
|
||||||
virtual ~Program(){
|
|
||||||
delete cmd;
|
|
||||||
delete psp;
|
|
||||||
}
|
|
||||||
std::string temp_line;
|
|
||||||
CommandLine * cmd;
|
|
||||||
DOS_PSP * psp;
|
|
||||||
virtual void Run(void)=0;
|
virtual void Run(void)=0;
|
||||||
bool GetEnvStr(const char * entry,std::string & result);
|
char * GetEnvStr(char * env_entry);
|
||||||
bool GetEnvNum(Bitu num,std::string & result);
|
char * GetEnvNum(Bit32u num);
|
||||||
Bitu GetEnvCount(void);
|
Bit32u GetEnvCount(void);
|
||||||
bool SetEnv(const char * entry,const char * new_string);
|
bool SetEnv(char * env_entry,char * new_string);
|
||||||
void WriteOut(const char * format,...); /* Write to standard output */
|
void WriteOut(char * format,...); /* Write to standard output */
|
||||||
void WriteOut_NoParsing(const char * format); /* Write to standard output, no parsing */
|
PROGRAM_Info * prog_info;
|
||||||
void ChangeToLongCmd();
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void (PROGRAMS_Main)(Program * * make);
|
void SHELL_AddAutoexec(char * line,...);
|
||||||
void PROGRAMS_MakeFile(char const * const name,PROGRAMS_Main * main);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
198
include/regs.h
198
include/regs.h
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2007 The DOSBox Team
|
* Copyright (C) 2002 The DOSBox Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -9,161 +9,109 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Library General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef DOSBOX_REGS_H
|
#if !defined __REGS_H
|
||||||
#define DOSBOX_REGS_H
|
#define __REGS_H
|
||||||
|
|
||||||
#ifndef DOSBOX_MEM_H
|
#include <mem.h>
|
||||||
#include "mem.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define FLAG_CF 0x00000001
|
struct Flag_Info {
|
||||||
#define FLAG_PF 0x00000004
|
union {
|
||||||
#define FLAG_AF 0x00000010
|
Bit8u b;
|
||||||
#define FLAG_ZF 0x00000040
|
Bit8u bs;
|
||||||
#define FLAG_SF 0x00000080
|
Bit16u w;
|
||||||
#define FLAG_OF 0x00000800
|
Bit16s ws;
|
||||||
|
Bit32u d;
|
||||||
|
Bit32s ds;
|
||||||
|
} var1,var2,result;
|
||||||
|
Bitu type;
|
||||||
|
Bitu prev_type;
|
||||||
|
bool cf,sf,pf,af,zf,of,df,tf,intf;
|
||||||
|
bool nt;
|
||||||
|
Bit8u io;
|
||||||
|
bool oldcf;
|
||||||
|
};
|
||||||
|
|
||||||
#define FLAG_TF 0x00000100
|
|
||||||
#define FLAG_IF 0x00000200
|
|
||||||
#define FLAG_DF 0x00000400
|
|
||||||
|
|
||||||
#define FLAG_IOPL 0x00003000
|
|
||||||
#define FLAG_NT 0x00004000
|
|
||||||
#define FLAG_VM 0x00020000
|
|
||||||
#define FLAG_AC 0x00040000
|
|
||||||
#define FLAG_ID 0x00200000
|
|
||||||
|
|
||||||
#define FMASK_TEST (FLAG_CF | FLAG_PF | FLAG_AF | FLAG_ZF | FLAG_SF | FLAG_OF)
|
|
||||||
#define FMASK_NORMAL (FMASK_TEST | FLAG_DF | FLAG_TF | FLAG_IF | FLAG_AC )
|
|
||||||
#define FMASK_ALL (FMASK_NORMAL | FLAG_IOPL | FLAG_NT)
|
|
||||||
|
|
||||||
#define SETFLAGBIT(TYPE,TEST) if (TEST) reg_flags|=FLAG_ ## TYPE; else reg_flags&=~FLAG_ ## TYPE
|
|
||||||
|
|
||||||
#define GETFLAG(TYPE) (reg_flags & FLAG_ ## TYPE)
|
|
||||||
#define GETFLAGBOOL(TYPE) ((reg_flags & FLAG_ ## TYPE) ? true : false )
|
|
||||||
|
|
||||||
#define GETFLAG_IOPL ((reg_flags & FLAG_IOPL) >> 12)
|
|
||||||
|
|
||||||
struct Segment {
|
struct Segment {
|
||||||
Bit16u val;
|
Bit16u value;
|
||||||
PhysPt phys; /* The phyiscal address start in emulated machine */
|
bool special; /* Signal for pointing to special memory */
|
||||||
|
HostOff host; /* The address of start in host memory */
|
||||||
|
PhysOff phys; /* The phyiscal address start in emulated machine */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SegNames { es=0,cs,ss,ds,fs,gs};
|
|
||||||
|
|
||||||
struct Segments {
|
|
||||||
Bitu val[8];
|
|
||||||
PhysPt phys[8];
|
|
||||||
};
|
|
||||||
|
|
||||||
union GenReg32 {
|
|
||||||
Bit32u dword[1];
|
|
||||||
Bit16u word[2];
|
|
||||||
Bit8u byte[4];
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef WORDS_BIGENDIAN
|
enum { cs=0,ds,es,fs,gs,ss};
|
||||||
|
|
||||||
#define DW_INDEX 0
|
extern Segment Segs[6];
|
||||||
#define W_INDEX 1
|
extern Flag_Info flags;
|
||||||
#define BH_INDEX 2
|
//extern Regs regs;
|
||||||
#define BL_INDEX 3
|
|
||||||
|
|
||||||
#else
|
void SetSegment_16(Bit32u seg,Bit16u val);
|
||||||
|
|
||||||
#define DW_INDEX 0
|
|
||||||
#define W_INDEX 0
|
|
||||||
#define BH_INDEX 1
|
|
||||||
#define BL_INDEX 0
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct CPU_Regs {
|
struct CPU_Regs {
|
||||||
GenReg32 regs[8],ip;
|
union {
|
||||||
Bitu flags;
|
Bit32u d;
|
||||||
|
Bit16u w;
|
||||||
|
struct {
|
||||||
|
Bit8u l,h;
|
||||||
|
}b;
|
||||||
|
} ax,bx,cx,dx,si,di,sp,bp,ip;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Segments Segs;
|
|
||||||
extern CPU_Regs cpu_regs;
|
extern CPU_Regs cpu_regs;
|
||||||
|
|
||||||
static INLINE PhysPt SegPhys(SegNames index) {
|
#define reg_al cpu_regs.ax.b.l
|
||||||
return Segs.phys[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE Bit16u SegValue(SegNames index) {
|
//extern Bit8u & reg_al=cpu_regs.ax.b.l;
|
||||||
return (Bit16u)Segs.val[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE RealPt RealMakeSeg(SegNames index,Bit16u off) {
|
#define reg_ah cpu_regs.ax.b.h
|
||||||
return RealMake(SegValue(index),off);
|
#define reg_ax cpu_regs.ax.w
|
||||||
}
|
#define reg_eax cpu_regs.ax.d
|
||||||
|
|
||||||
|
#define reg_bl cpu_regs.bx.b.l
|
||||||
|
#define reg_bh cpu_regs.bx.b.h
|
||||||
|
#define reg_bx cpu_regs.bx.w
|
||||||
|
#define reg_ebx cpu_regs.bx.d
|
||||||
|
|
||||||
|
#define reg_cl cpu_regs.cx.b.l
|
||||||
|
#define reg_ch cpu_regs.cx.b.h
|
||||||
|
#define reg_cx cpu_regs.cx.w
|
||||||
|
#define reg_ecx cpu_regs.cx.d
|
||||||
|
|
||||||
|
#define reg_dl cpu_regs.dx.b.l
|
||||||
|
#define reg_dh cpu_regs.dx.b.h
|
||||||
|
#define reg_dx cpu_regs.dx.w
|
||||||
|
#define reg_edx cpu_regs.dx.d
|
||||||
|
|
||||||
|
#define reg_si cpu_regs.si.w
|
||||||
|
#define reg_esi cpu_regs.si.d
|
||||||
|
|
||||||
|
#define reg_di cpu_regs.di.w
|
||||||
|
#define reg_edi cpu_regs.di.d
|
||||||
|
|
||||||
|
#define reg_sp cpu_regs.sp.w
|
||||||
|
#define reg_esp cpu_regs.sp.d
|
||||||
|
|
||||||
|
#define reg_bp cpu_regs.bp.w
|
||||||
|
#define reg_ebp cpu_regs.bp.d
|
||||||
|
|
||||||
|
#define reg_ip cpu_regs.ip.w
|
||||||
|
#define reg_eip cpu_regs.ip.d
|
||||||
|
|
||||||
|
|
||||||
static INLINE void SegSet16(Bitu index,Bit16u val) {
|
|
||||||
Segs.val[index]=val;
|
|
||||||
Segs.phys[index]=val << 4;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum {
|
|
||||||
REGI_AX, REGI_CX, REGI_DX, REGI_BX,
|
|
||||||
REGI_SP, REGI_BP, REGI_SI, REGI_DI
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
REGI_AL, REGI_CL, REGI_DL, REGI_BL,
|
|
||||||
REGI_AH, REGI_CH, REGI_DH, REGI_BH
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//macros to convert a 3-bit register index to the correct register
|
|
||||||
#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)].word[W_INDEX])
|
|
||||||
#define reg_32(reg) (cpu_regs.regs[(reg)].dword[DW_INDEX])
|
|
||||||
|
|
||||||
#define reg_al cpu_regs.regs[REGI_AX].byte[BL_INDEX]
|
|
||||||
#define reg_ah cpu_regs.regs[REGI_AX].byte[BH_INDEX]
|
|
||||||
#define reg_ax cpu_regs.regs[REGI_AX].word[W_INDEX]
|
|
||||||
#define reg_eax cpu_regs.regs[REGI_AX].dword[DW_INDEX]
|
|
||||||
|
|
||||||
#define reg_bl cpu_regs.regs[REGI_BX].byte[BL_INDEX]
|
|
||||||
#define reg_bh cpu_regs.regs[REGI_BX].byte[BH_INDEX]
|
|
||||||
#define reg_bx cpu_regs.regs[REGI_BX].word[W_INDEX]
|
|
||||||
#define reg_ebx cpu_regs.regs[REGI_BX].dword[DW_INDEX]
|
|
||||||
|
|
||||||
#define reg_cl cpu_regs.regs[REGI_CX].byte[BL_INDEX]
|
|
||||||
#define reg_ch cpu_regs.regs[REGI_CX].byte[BH_INDEX]
|
|
||||||
#define reg_cx cpu_regs.regs[REGI_CX].word[W_INDEX]
|
|
||||||
#define reg_ecx cpu_regs.regs[REGI_CX].dword[DW_INDEX]
|
|
||||||
|
|
||||||
#define reg_dl cpu_regs.regs[REGI_DX].byte[BL_INDEX]
|
|
||||||
#define reg_dh cpu_regs.regs[REGI_DX].byte[BH_INDEX]
|
|
||||||
#define reg_dx cpu_regs.regs[REGI_DX].word[W_INDEX]
|
|
||||||
#define reg_edx cpu_regs.regs[REGI_DX].dword[DW_INDEX]
|
|
||||||
|
|
||||||
#define reg_si cpu_regs.regs[REGI_SI].word[W_INDEX]
|
|
||||||
#define reg_esi cpu_regs.regs[REGI_SI].dword[DW_INDEX]
|
|
||||||
|
|
||||||
#define reg_di cpu_regs.regs[REGI_DI].word[W_INDEX]
|
|
||||||
#define reg_edi cpu_regs.regs[REGI_DI].dword[DW_INDEX]
|
|
||||||
|
|
||||||
#define reg_sp cpu_regs.regs[REGI_SP].word[W_INDEX]
|
|
||||||
#define reg_esp cpu_regs.regs[REGI_SP].dword[DW_INDEX]
|
|
||||||
|
|
||||||
#define reg_bp cpu_regs.regs[REGI_BP].word[W_INDEX]
|
|
||||||
#define reg_ebp cpu_regs.regs[REGI_BP].dword[DW_INDEX]
|
|
||||||
|
|
||||||
#define reg_ip cpu_regs.ip.word[W_INDEX]
|
|
||||||
#define reg_eip cpu_regs.ip.dword[DW_INDEX]
|
|
||||||
|
|
||||||
#define reg_flags cpu_regs.flags
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2007 The DOSBox Team
|
* Copyright (C) 2002 The DOSBox Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -9,90 +9,17 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Library General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef DOSBOX_RENDER_H
|
|
||||||
#define DOSBOX_RENDER_H
|
|
||||||
|
|
||||||
// 0: complex scalers off, scaler cache off, some simple scalers off, memory requirements reduced
|
typedef void RENDER_Handler(Bit8u * * data);
|
||||||
// 1: complex scalers off, scaler cache off, all simple scalers on
|
|
||||||
// 2: complex scalers off, scaler cache on
|
|
||||||
// 3: complex scalers on
|
|
||||||
#define RENDER_USE_ADVANCED_SCALERS 3
|
|
||||||
|
|
||||||
#include "../src/gui/render_scalers.h"
|
|
||||||
|
|
||||||
#define RENDER_SKIP_CACHE 16
|
void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,Bitu pitch,float ratio,Bitu flags, RENDER_Handler * handler);
|
||||||
//Enable this for scalers to support 0 input for empty lines
|
|
||||||
//#define RENDER_NULL_INPUT
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
struct {
|
|
||||||
Bit8u red;
|
|
||||||
Bit8u green;
|
|
||||||
Bit8u blue;
|
|
||||||
Bit8u unused;
|
|
||||||
} rgb[256];
|
|
||||||
union {
|
|
||||||
Bit16u b16[256];
|
|
||||||
Bit32u b32[256];
|
|
||||||
} lut;
|
|
||||||
bool changed;
|
|
||||||
Bit8u modified[256];
|
|
||||||
Bitu first;
|
|
||||||
Bitu last;
|
|
||||||
} RenderPal_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
struct {
|
|
||||||
Bitu width, start;
|
|
||||||
Bitu height;
|
|
||||||
Bitu bpp;
|
|
||||||
bool dblw,dblh;
|
|
||||||
double ratio;
|
|
||||||
float fps;
|
|
||||||
} src;
|
|
||||||
struct {
|
|
||||||
Bitu count;
|
|
||||||
Bitu max;
|
|
||||||
Bitu index;
|
|
||||||
Bit8u hadSkip[RENDER_SKIP_CACHE];
|
|
||||||
} frameskip;
|
|
||||||
struct {
|
|
||||||
Bitu size;
|
|
||||||
scalerMode_t inMode;
|
|
||||||
scalerMode_t outMode;
|
|
||||||
scalerOperation_t op;
|
|
||||||
bool clearCache;
|
|
||||||
bool forced;
|
|
||||||
ScalerLineHandler_t lineHandler;
|
|
||||||
ScalerLineHandler_t linePalHandler;
|
|
||||||
ScalerComplexHandler_t complexHandler;
|
|
||||||
Bitu blocks, lastBlock;
|
|
||||||
Bitu outPitch;
|
|
||||||
Bit8u *outWrite;
|
|
||||||
Bitu cachePitch;
|
|
||||||
Bit8u *cacheRead;
|
|
||||||
Bitu inHeight, inLine, outLine;
|
|
||||||
} scale;
|
|
||||||
RenderPal_t pal;
|
|
||||||
bool updating;
|
|
||||||
bool active;
|
|
||||||
bool aspect;
|
|
||||||
bool fullFrame;
|
|
||||||
} Render_t;
|
|
||||||
|
|
||||||
extern Render_t render;
|
|
||||||
extern ScalerLineHandler_t RENDER_DrawLine;
|
|
||||||
void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,float fps,double ratio,bool dblw,bool dblh);
|
|
||||||
bool RENDER_StartUpdate(void);
|
|
||||||
void RENDER_EndUpdate( );
|
|
||||||
void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue);
|
void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
@ -1,361 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2002-2007 The DOSBox Team
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* $Id: serialport.h,v 1.16 2009/02/01 14:11:45 qbix79 Exp $ */
|
|
||||||
|
|
||||||
#ifndef DOSBOX_SERIALPORT_H
|
|
||||||
#define DOSBOX_SERIALPORT_H
|
|
||||||
|
|
||||||
#define SERIAL_DEBUG 0
|
|
||||||
|
|
||||||
// Uncomment this for a lot of debug messages:
|
|
||||||
//#define LOG_UART
|
|
||||||
|
|
||||||
#ifndef DOSBOX_DOSBOX_H
|
|
||||||
#include "dosbox.h"
|
|
||||||
#endif
|
|
||||||
#ifndef DOSBOX_INOUT_H
|
|
||||||
#include "inout.h"
|
|
||||||
#endif
|
|
||||||
#ifndef DOSBOX_TIMER_H
|
|
||||||
#include "timer.h"
|
|
||||||
#endif
|
|
||||||
#ifndef DOSBOX_DOS_INC_H
|
|
||||||
#include "dos_inc.h"
|
|
||||||
#endif
|
|
||||||
#ifndef DOSBOX_PROGRAMS_H
|
|
||||||
#include "programs.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if SERIAL_DEBUG
|
|
||||||
#include "hardware.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Serial port interface
|
|
||||||
|
|
||||||
class CSerial {
|
|
||||||
public:
|
|
||||||
|
|
||||||
#if SERIAL_DEBUG
|
|
||||||
FILE * debugfp;
|
|
||||||
bool dbg_modemcontrol; // RTS,CTS,DTR,DSR,RI,CD
|
|
||||||
bool dbg_serialtraffic;
|
|
||||||
bool dbg_register;
|
|
||||||
bool dbg_interrupt;
|
|
||||||
bool dbg_aux;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static bool getBituSubstring(const char* name,Bitu* data, CommandLine* cmd);
|
|
||||||
|
|
||||||
bool InstallationSuccessful;// check after constructing. If
|
|
||||||
// something was wrong, delete it right away.
|
|
||||||
|
|
||||||
// Constructor takes com port number (0-3)
|
|
||||||
CSerial(Bitu id, CommandLine* cmd);
|
|
||||||
|
|
||||||
virtual ~CSerial();
|
|
||||||
|
|
||||||
IO_ReadHandleObject ReadHandler[8];
|
|
||||||
IO_WriteHandleObject WriteHandler[8];
|
|
||||||
|
|
||||||
float bytetime; // how long a byte takes to transmit/receive in milliseconds
|
|
||||||
void changeLineProperties();
|
|
||||||
Bitu idnumber;
|
|
||||||
|
|
||||||
void setEvent(Bit16u type, float duration);
|
|
||||||
void removeEvent(Bit16u type);
|
|
||||||
void handleEvent(Bit16u type);
|
|
||||||
virtual void handleUpperEvent(Bit16u type)=0;
|
|
||||||
|
|
||||||
// defines for event type
|
|
||||||
#define SERIAL_TX_LOOPBACK_EVENT 0
|
|
||||||
#define SERIAL_THR_LOOPBACK_EVENT 1
|
|
||||||
#define SERIAL_ERRMSG_EVENT 2
|
|
||||||
|
|
||||||
#define SERIAL_TX_EVENT 3
|
|
||||||
#define SERIAL_RX_EVENT 4
|
|
||||||
#define SERIAL_POLLING_EVENT 5
|
|
||||||
#define SERIAL_THR_EVENT 6
|
|
||||||
|
|
||||||
#define SERIAL_BASE_EVENT_COUNT 6
|
|
||||||
|
|
||||||
#define COMNUMBER idnumber+1
|
|
||||||
|
|
||||||
Bitu irq;
|
|
||||||
|
|
||||||
// CSerial requests an update of the input lines
|
|
||||||
virtual void updateMSR()=0;
|
|
||||||
|
|
||||||
// Control lines from prepherial to serial port
|
|
||||||
bool getDTR();
|
|
||||||
bool getRTS();
|
|
||||||
|
|
||||||
bool getRI();
|
|
||||||
bool getCD();
|
|
||||||
bool getDSR();
|
|
||||||
bool getCTS();
|
|
||||||
|
|
||||||
void setRI(bool value);
|
|
||||||
void setDSR(bool value);
|
|
||||||
void setCD(bool value);
|
|
||||||
void setCTS(bool value);
|
|
||||||
|
|
||||||
// From serial port to prepherial
|
|
||||||
// set output lines
|
|
||||||
virtual void setRTSDTR(bool rts, bool dtr)=0;
|
|
||||||
virtual void setRTS(bool val)=0;
|
|
||||||
virtual void setDTR(bool val)=0;
|
|
||||||
|
|
||||||
// Register access
|
|
||||||
void Write_THR(Bit8u data);
|
|
||||||
void Write_IER(Bit8u data);
|
|
||||||
void Write_FCR(Bit8u data);
|
|
||||||
void Write_LCR(Bit8u data);
|
|
||||||
void Write_MCR(Bit8u data);
|
|
||||||
// Really old hardware seems to have the delta part of this register writable
|
|
||||||
void Write_MSR(Bit8u data);
|
|
||||||
void Write_SPR(Bit8u data);
|
|
||||||
void Write_reserved(Bit8u data, Bit8u address);
|
|
||||||
|
|
||||||
Bitu Read_RHR();
|
|
||||||
Bitu Read_IER();
|
|
||||||
Bitu Read_ISR();
|
|
||||||
Bitu Read_LCR();
|
|
||||||
Bitu Read_MCR();
|
|
||||||
Bitu Read_LSR();
|
|
||||||
Bitu Read_MSR();
|
|
||||||
Bitu Read_SPR();
|
|
||||||
|
|
||||||
// If a byte comes from loopback or prepherial, put it in here.
|
|
||||||
void receiveByte(Bit8u data);
|
|
||||||
|
|
||||||
// If an error was received, put it here (in LSR register format)
|
|
||||||
void receiveError(Bit8u errorword);
|
|
||||||
|
|
||||||
// depratched
|
|
||||||
// connected device checks, if port can receive data:
|
|
||||||
bool CanReceiveByte();
|
|
||||||
|
|
||||||
// when THR was shifted to TX
|
|
||||||
void ByteTransmitting();
|
|
||||||
|
|
||||||
// When done sending, notify here
|
|
||||||
void ByteTransmitted();
|
|
||||||
|
|
||||||
// Transmit byte to prepherial
|
|
||||||
virtual void transmitByte(Bit8u val, bool first)=0;
|
|
||||||
|
|
||||||
// switch break state to the passed value
|
|
||||||
virtual void setBreak(bool value)=0;
|
|
||||||
|
|
||||||
// change baudrate, number of bits, parity, word length al at once
|
|
||||||
virtual void updatePortConfig(Bit16u divider, Bit8u lcr)=0;
|
|
||||||
|
|
||||||
void Init_Registers();
|
|
||||||
|
|
||||||
bool Putchar(Bit8u data, bool wait_dtr, bool wait_rts, Bitu timeout);
|
|
||||||
bool Getchar(Bit8u* data, Bit8u* lsr, bool wait_dsr, Bitu timeout);
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
DOS_Device* mydosdevice;
|
|
||||||
|
|
||||||
// I used this spec: http://www.exar.com/products/st16c450v420.pdf
|
|
||||||
|
|
||||||
void ComputeInterrupts();
|
|
||||||
|
|
||||||
// a sub-interrupt is triggered
|
|
||||||
void rise(Bit8u priority);
|
|
||||||
|
|
||||||
// clears the pending sub-interrupt
|
|
||||||
void clear(Bit8u priority);
|
|
||||||
|
|
||||||
#define ERROR_PRIORITY 4 // overrun, parity error, frame error, break
|
|
||||||
#define RX_PRIORITY 1 // a byte has been received
|
|
||||||
#define TX_PRIORITY 2 // tx buffer has become empty
|
|
||||||
#define MSR_PRIORITY 8 // CRS, DSR, RI, DCD change
|
|
||||||
#define NONE_PRIORITY 0
|
|
||||||
|
|
||||||
Bit8u waiting_interrupts; // these are on, but maybe not enabled
|
|
||||||
|
|
||||||
// 16C450 (no FIFO)
|
|
||||||
// read/write name
|
|
||||||
|
|
||||||
Bit16u baud_divider;
|
|
||||||
Bit8u RHR; // r Receive Holding Register, also LSB of Divisor Latch (r/w)
|
|
||||||
#define RHR_OFFSET 0
|
|
||||||
// Data: whole byte
|
|
||||||
|
|
||||||
Bit8u THR; // w Transmit Holding Register
|
|
||||||
#define THR_OFFSET 0
|
|
||||||
// Data: whole byte
|
|
||||||
|
|
||||||
Bit8u IER; // r/w Interrupt Enable Register, also MSB of Divisor Latch
|
|
||||||
#define IER_OFFSET 1
|
|
||||||
|
|
||||||
bool irq_active;
|
|
||||||
|
|
||||||
#define RHR_INT_Enable_MASK 0x1
|
|
||||||
#define THR_INT_Enable_MASK 0x2
|
|
||||||
#define Receive_Line_INT_Enable_MASK 0x4
|
|
||||||
#define Modem_Status_INT_Enable_MASK 0x8
|
|
||||||
|
|
||||||
Bit8u ISR; // r Interrupt Status Register
|
|
||||||
#define ISR_OFFSET 2
|
|
||||||
|
|
||||||
#define ISR_CLEAR_VAL 0x1
|
|
||||||
#define ISR_ERROR_VAL 0x6
|
|
||||||
#define ISR_RX_VAL 0x4
|
|
||||||
#define ISR_TX_VAL 0x2
|
|
||||||
#define ISR_MSR_VAL 0x0
|
|
||||||
public:
|
|
||||||
Bit8u LCR; // r/w Line Control Register
|
|
||||||
private:
|
|
||||||
#define LCR_OFFSET 3
|
|
||||||
// bit0: word length bit0
|
|
||||||
// bit1: word length bit1
|
|
||||||
// bit2: stop bits
|
|
||||||
// bit3: parity enable
|
|
||||||
// bit4: even parity
|
|
||||||
// bit5: set parity
|
|
||||||
// bit6: set break
|
|
||||||
// bit7: divisor latch enable
|
|
||||||
|
|
||||||
|
|
||||||
#define LCR_BREAK_MASK 0x40
|
|
||||||
#define LCR_DIVISOR_Enable_MASK 0x80
|
|
||||||
#define LCR_PORTCONFIG_MASK 0x3F
|
|
||||||
|
|
||||||
#define LCR_PARITY_NONE 0x0
|
|
||||||
#define LCR_PARITY_ODD 0x8
|
|
||||||
#define LCR_PARITY_EVEN 0x18
|
|
||||||
#define LCR_PARITY_MARK 0x28
|
|
||||||
#define LCR_PARITY_SPACE 0x38
|
|
||||||
|
|
||||||
#define LCR_DATABITS_5 0x0
|
|
||||||
#define LCR_DATABITS_6 0x1
|
|
||||||
#define LCR_DATABITS_7 0x2
|
|
||||||
#define LCR_DATABITS_8 0x3
|
|
||||||
|
|
||||||
#define LCR_STOPBITS_1 0x0
|
|
||||||
#define LCR_STOPBITS_MORE_THAN_1 0x4
|
|
||||||
|
|
||||||
// Modem Control Register
|
|
||||||
// r/w
|
|
||||||
#define MCR_OFFSET 4
|
|
||||||
bool dtr; // bit0: DTR
|
|
||||||
bool rts; // bit1: RTS
|
|
||||||
bool op1; // bit2: OP1
|
|
||||||
bool op2; // bit3: OP2
|
|
||||||
bool loopback; // bit4: loop back enable
|
|
||||||
|
|
||||||
#define MCR_DTR_MASK 0x1
|
|
||||||
#define MCR_RTS_MASK 0x2
|
|
||||||
#define MCR_OP1_MASK 0x4
|
|
||||||
#define MCR_OP2_MASK 0x8
|
|
||||||
#define MCR_LOOPBACK_Enable_MASK 0x10
|
|
||||||
public:
|
|
||||||
Bit8u LSR; // r Line Status Register
|
|
||||||
private:
|
|
||||||
|
|
||||||
#define LSR_OFFSET 5
|
|
||||||
|
|
||||||
#define LSR_RX_DATA_READY_MASK 0x1
|
|
||||||
#define LSR_OVERRUN_ERROR_MASK 0x2
|
|
||||||
#define LSR_PARITY_ERROR_MASK 0x4
|
|
||||||
#define LSR_FRAMING_ERROR_MASK 0x8
|
|
||||||
#define LSR_RX_BREAK_MASK 0x10
|
|
||||||
#define LSR_TX_HOLDING_EMPTY_MASK 0x20
|
|
||||||
#define LSR_TX_EMPTY_MASK 0x40
|
|
||||||
|
|
||||||
#define LSR_ERROR_MASK 0x1e
|
|
||||||
|
|
||||||
// error printing
|
|
||||||
bool errormsg_pending;
|
|
||||||
Bitu framingErrors;
|
|
||||||
Bitu parityErrors;
|
|
||||||
Bitu overrunErrors;
|
|
||||||
Bitu overrunIF0;
|
|
||||||
Bitu breakErrors;
|
|
||||||
|
|
||||||
|
|
||||||
// Modem Status Register
|
|
||||||
// r
|
|
||||||
#define MSR_OFFSET 6
|
|
||||||
bool d_cts; // bit0: deltaCTS
|
|
||||||
bool d_dsr; // bit1: deltaDSR
|
|
||||||
bool d_ri; // bit2: deltaRI
|
|
||||||
bool d_cd; // bit3: deltaCD
|
|
||||||
bool cts; // bit4: CTS
|
|
||||||
bool dsr; // bit5: DSR
|
|
||||||
bool ri; // bit6: RI
|
|
||||||
bool cd; // bit7: CD
|
|
||||||
|
|
||||||
#define MSR_delta_MASK 0xf
|
|
||||||
#define MSR_LINE_MASK 0xf0
|
|
||||||
|
|
||||||
#define MSR_dCTS_MASK 0x1
|
|
||||||
#define MSR_dDSR_MASK 0x2
|
|
||||||
#define MSR_dRI_MASK 0x4
|
|
||||||
#define MSR_dCD_MASK 0x8
|
|
||||||
#define MSR_CTS_MASK 0x10
|
|
||||||
#define MSR_DSR_MASK 0x20
|
|
||||||
#define MSR_RI_MASK 0x40
|
|
||||||
#define MSR_CD_MASK 0x80
|
|
||||||
|
|
||||||
Bit8u SPR; // r/w Scratchpad Register
|
|
||||||
#define SPR_OFFSET 7
|
|
||||||
|
|
||||||
|
|
||||||
// For loopback purposes...
|
|
||||||
Bit8u loopback_data;
|
|
||||||
void transmitLoopbackByte(Bit8u val, bool value);
|
|
||||||
|
|
||||||
// 16C550 (FIFO)
|
|
||||||
// TODO
|
|
||||||
#define FCR_OFFSET 2
|
|
||||||
bool fifo_warn;
|
|
||||||
//Bit8u FCR; // FIFO Control Register
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
extern CSerial* serialports[];
|
|
||||||
const Bit8u serial_defaultirq[4] = { 4, 3, 4, 3 };
|
|
||||||
const Bit16u serial_baseaddr[4] = {0x3f8,0x2f8,0x3e8,0x2e8};
|
|
||||||
const char* const serial_comname[]={"COM1","COM2","COM3","COM4"};
|
|
||||||
|
|
||||||
// the COM devices
|
|
||||||
|
|
||||||
class device_COM : public DOS_Device {
|
|
||||||
public:
|
|
||||||
// Creates a COM device that communicates with the num-th parallel port, i.e. is LPTnum
|
|
||||||
device_COM(class CSerial* sc);
|
|
||||||
~device_COM();
|
|
||||||
bool Read(Bit8u * data,Bit16u * size);
|
|
||||||
bool Write(Bit8u * data,Bit16u * size);
|
|
||||||
bool Seek(Bit32u * pos,Bit32u type);
|
|
||||||
bool Close();
|
|
||||||
Bit16u GetInformation(void);
|
|
||||||
private:
|
|
||||||
CSerial* sclass;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
336
include/setup.h
336
include/setup.h
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2008 The DOSBox Team
|
* Copyright (C) 2002 The DOSBox Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -9,323 +9,35 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Library General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: setup.h,v 1.40 2009/02/15 20:01:08 qbix79 Exp $ */
|
#ifndef _SETUP_H_
|
||||||
|
#define _SETUP_H_
|
||||||
|
|
||||||
#ifndef DOSBOX_SETUP_H
|
#include <cross.h>
|
||||||
#define DOSBOX_SETUP_H
|
enum { S_STRING,S_HEX,S_INT,S_BOOL};
|
||||||
|
|
||||||
|
typedef char *(String_Handler)(char * input);
|
||||||
|
typedef char *(Hex_Handler)(Bitu * input);
|
||||||
|
typedef char *(Int_Handler)(Bits * input);
|
||||||
|
typedef char *(Bool_Handler)(bool input);
|
||||||
|
|
||||||
|
class Setup {
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
int argc;
|
||||||
|
char * * argv;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
extern char dosbox_basedir[CROSS_LEN];
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning ( disable : 4786 )
|
|
||||||
#pragma warning ( disable : 4290 )
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef CH_LIST
|
|
||||||
#define CH_LIST
|
|
||||||
#include <list>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CH_VECTOR
|
|
||||||
#define CH_VECTOR
|
|
||||||
#include <vector>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef CH_STRING
|
|
||||||
#define CH_STRING
|
|
||||||
#include <string>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
class Hex {
|
|
||||||
private:
|
|
||||||
int _hex;
|
|
||||||
public:
|
|
||||||
Hex(int in):_hex(in) { };
|
|
||||||
Hex():_hex(0) { };
|
|
||||||
bool operator==(Hex const& other) {return _hex == other._hex;}
|
|
||||||
operator int () const { return _hex; }
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class Value {
|
|
||||||
/*
|
|
||||||
* Multitype storage container that is aware of the currently stored type in it.
|
|
||||||
* Value st = "hello";
|
|
||||||
* Value in = 1;
|
|
||||||
* st = 12 //Exception
|
|
||||||
* in = 12 //works
|
|
||||||
*/
|
|
||||||
private:
|
|
||||||
Hex _hex;
|
|
||||||
bool _bool;
|
|
||||||
int _int;
|
|
||||||
std::string* _string;
|
|
||||||
double _double;
|
|
||||||
public:
|
|
||||||
class WrongType { }; // Conversion error class
|
|
||||||
enum Etype { V_NONE, V_HEX, V_BOOL, V_INT, V_STRING, V_DOUBLE,V_CURRENT} type;
|
|
||||||
|
|
||||||
/* Constructors */
|
|
||||||
Value() :_string(0), type(V_NONE) { };
|
|
||||||
Value(Hex in) :_hex(in), type(V_HEX) { };
|
|
||||||
Value(int in) :_int(in), type(V_INT) { };
|
|
||||||
Value(bool in) :_bool(in), type(V_BOOL) { };
|
|
||||||
Value(double in) :_double(in), type(V_DOUBLE) { };
|
|
||||||
Value(std::string const& in) :_string(new std::string(in)),type(V_STRING) { };
|
|
||||||
Value(char const * const in) :_string(new std::string(in)),type(V_STRING) { };
|
|
||||||
Value(Value const& in):_string(0) {plaincopy(in);}
|
|
||||||
~Value() { destroy();};
|
|
||||||
Value(std::string const& in,Etype _t) :_string(0),type(V_NONE) {SetValue(in,_t);}
|
|
||||||
|
|
||||||
/* Assigment operators */
|
|
||||||
Value& operator= (Hex in) throw(WrongType) { return copy(Value(in));}
|
|
||||||
Value& operator= (int in) throw(WrongType) { return copy(Value(in));}
|
|
||||||
Value& operator= (bool in) throw(WrongType) { return copy(Value(in));}
|
|
||||||
Value& operator= (double in) throw(WrongType) { return copy(Value(in));}
|
|
||||||
Value& operator= (std::string const& in) throw(WrongType) { return copy(Value(in));}
|
|
||||||
Value& operator= (char const * const in) throw(WrongType) { return copy(Value(in));}
|
|
||||||
Value& operator= (Value const& in) throw(WrongType) { return copy(Value(in));}
|
|
||||||
|
|
||||||
bool operator== (Value const & other);
|
|
||||||
operator bool () const throw(WrongType);
|
|
||||||
operator Hex () const throw(WrongType);
|
|
||||||
operator int () const throw(WrongType);
|
|
||||||
operator double () const throw(WrongType);
|
|
||||||
operator char const* () const throw(WrongType);
|
|
||||||
void SetValue(std::string const& in,Etype _type = V_CURRENT) throw(WrongType);
|
|
||||||
std::string ToString() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
void destroy() throw();
|
|
||||||
Value& copy(Value const& in) throw(WrongType);
|
|
||||||
void plaincopy(Value const& in) throw();
|
|
||||||
void set_hex(std::string const& in);
|
|
||||||
void set_int(std::string const&in);
|
|
||||||
void set_bool(std::string const& in);
|
|
||||||
void set_string(std::string const& in);
|
|
||||||
void set_double(std::string const& in);
|
|
||||||
};
|
|
||||||
|
|
||||||
class Property {
|
|
||||||
public:
|
|
||||||
struct Changeable { enum Value {Always, WhenIdle,OnlyAtStart};};
|
|
||||||
const std::string propname;
|
|
||||||
|
|
||||||
Property(std::string const& _propname, Changeable::Value when):propname(_propname),change(when) { }
|
|
||||||
void Set_values(const char * const * in);
|
|
||||||
void Set_help(std::string const& str);
|
|
||||||
char const* Get_help();
|
|
||||||
virtual void SetValue(std::string const& str)=0;
|
|
||||||
Value const& GetValue() const { return value;}
|
|
||||||
Value const& Get_Default_Value() const { return default_value; }
|
|
||||||
//CheckValue returns true if value is in suggested_values;
|
|
||||||
//Type specific properties are encouraged to override this and check for type
|
|
||||||
//specific features.
|
|
||||||
virtual bool CheckValue(Value const& in, bool warn);
|
|
||||||
//Set interval value to in or default if in is invalid. force always sets the value.
|
|
||||||
void SetVal(Value const& in, bool forced,bool warn=true) {if(forced || CheckValue(in,warn)) value = in; else value = default_value;}
|
|
||||||
virtual ~Property(){ }
|
|
||||||
virtual const std::vector<Value>& GetValues() const;
|
|
||||||
Value::Etype Get_type(){return default_value.type;}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Value value;
|
|
||||||
std::vector<Value> suggested_values;
|
|
||||||
typedef std::vector<Value>::iterator iter;
|
|
||||||
Value default_value;
|
|
||||||
const Changeable::Value change;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Prop_int:public Property {
|
|
||||||
public:
|
|
||||||
Prop_int(std::string const& _propname,Changeable::Value when, int _value)
|
|
||||||
:Property(_propname,when) {
|
|
||||||
default_value = value = _value;
|
|
||||||
min = max = -1;
|
|
||||||
}
|
|
||||||
Prop_int(std::string const& _propname,Changeable::Value when, int _min,int _max,int _value)
|
|
||||||
:Property(_propname,when) {
|
|
||||||
default_value = value = _value;
|
|
||||||
min = _min;
|
|
||||||
max = _max;
|
|
||||||
}
|
|
||||||
void SetMinMax(Value const& min,Value const& max) {this->min = min; this->max=max;}
|
|
||||||
void SetValue(std::string const& in);
|
|
||||||
~Prop_int(){ }
|
|
||||||
virtual bool CheckValue(Value const& in, bool warn);
|
|
||||||
private:
|
|
||||||
Value min,max;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Prop_double:public Property {
|
|
||||||
public:
|
|
||||||
Prop_double(std::string const & _propname, Changeable::Value when, double _value)
|
|
||||||
:Property(_propname,when){
|
|
||||||
default_value = value = _value;
|
|
||||||
}
|
|
||||||
void SetValue(std::string const& input);
|
|
||||||
~Prop_double(){ }
|
|
||||||
};
|
|
||||||
|
|
||||||
class Prop_bool:public Property {
|
|
||||||
public:
|
|
||||||
Prop_bool(std::string const& _propname, Changeable::Value when, bool _value)
|
|
||||||
:Property(_propname,when) {
|
|
||||||
default_value = value = _value;
|
|
||||||
}
|
|
||||||
void SetValue(std::string const& in);
|
|
||||||
~Prop_bool(){ }
|
|
||||||
};
|
|
||||||
|
|
||||||
class Prop_string:public Property{
|
|
||||||
public:
|
|
||||||
Prop_string(std::string const& _propname, Changeable::Value when, char const * const _value)
|
|
||||||
:Property(_propname,when) {
|
|
||||||
default_value = value = _value;
|
|
||||||
}
|
|
||||||
void SetValue(std::string const& in);
|
|
||||||
virtual bool CheckValue(Value const& in, bool warn);
|
|
||||||
~Prop_string(){ }
|
|
||||||
};
|
|
||||||
class Prop_path:public Prop_string{
|
|
||||||
public:
|
|
||||||
std::string realpath;
|
|
||||||
Prop_path(std::string const& _propname, Changeable::Value when, char const * const _value)
|
|
||||||
:Prop_string(_propname,when,_value) {
|
|
||||||
default_value = value = _value;
|
|
||||||
realpath = _value;
|
|
||||||
}
|
|
||||||
void SetValue(std::string const& in);
|
|
||||||
~Prop_path(){ }
|
|
||||||
};
|
|
||||||
|
|
||||||
class Prop_hex:public Property {
|
|
||||||
public:
|
|
||||||
Prop_hex(std::string const& _propname, Changeable::Value when, Hex _value)
|
|
||||||
:Property(_propname,when) {
|
|
||||||
default_value = value = _value;
|
|
||||||
}
|
|
||||||
void SetValue(std::string const& in);
|
|
||||||
~Prop_hex(){ }
|
|
||||||
};
|
|
||||||
|
|
||||||
#define NO_SUCH_PROPERTY "PROP_NOT_EXIST"
|
|
||||||
class Section {
|
|
||||||
private:
|
|
||||||
typedef void (*SectionFunction)(Section*);
|
|
||||||
/* Wrapper class around startup and shutdown functions. the variable
|
|
||||||
* canchange indicates it can be called on configuration changes */
|
|
||||||
struct Function_wrapper {
|
|
||||||
SectionFunction function;
|
|
||||||
bool canchange;
|
|
||||||
Function_wrapper(SectionFunction const _fun,bool _ch){
|
|
||||||
function=_fun;
|
|
||||||
canchange=_ch;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
std::list<Function_wrapper> initfunctions;
|
|
||||||
std::list<Function_wrapper> destroyfunctions;
|
|
||||||
std::string sectionname;
|
|
||||||
public:
|
|
||||||
Section(std::string const& _sectionname):sectionname(_sectionname) { }
|
|
||||||
|
|
||||||
void AddInitFunction(SectionFunction func,bool canchange=false);
|
|
||||||
void AddDestroyFunction(SectionFunction func,bool canchange=false);
|
|
||||||
void ExecuteInit(bool initall=true);
|
|
||||||
void ExecuteDestroy(bool destroyall=true);
|
|
||||||
const char* GetName() const {return sectionname.c_str();}
|
|
||||||
|
|
||||||
virtual std::string GetPropValue(std::string const& _property) const =0;
|
|
||||||
virtual void HandleInputline(std::string const& _line)=0;
|
|
||||||
virtual void PrintData(FILE* outfile) const =0;
|
|
||||||
virtual ~Section() { /*Children must call executedestroy ! */}
|
|
||||||
};
|
|
||||||
|
|
||||||
class Prop_multival;
|
|
||||||
class Prop_multival_remain;
|
|
||||||
class Section_prop:public Section {
|
|
||||||
private:
|
|
||||||
std::list<Property*> properties;
|
|
||||||
typedef std::list<Property*>::iterator it;
|
|
||||||
typedef std::list<Property*>::const_iterator const_it;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Section_prop(std::string const& _sectionname):Section(_sectionname){}
|
|
||||||
Prop_int* Add_int(std::string const& _propname, Property::Changeable::Value when, int _value=0);
|
|
||||||
Prop_string* Add_string(std::string const& _propname, Property::Changeable::Value when, char const * const _value=NULL);
|
|
||||||
Prop_path* Add_path(std::string const& _propname, Property::Changeable::Value when, char const * const _value=NULL);
|
|
||||||
Prop_bool* Add_bool(std::string const& _propname, Property::Changeable::Value when, bool _value=false);
|
|
||||||
Prop_hex* Add_hex(std::string const& _propname, Property::Changeable::Value when, Hex _value=0);
|
|
||||||
// void Add_double(char const * const _propname, double _value=0.0);
|
|
||||||
Prop_multival *Add_multi(std::string const& _propname, Property::Changeable::Value when,std::string const& sep);
|
|
||||||
Prop_multival_remain *Add_multiremain(std::string const& _propname, Property::Changeable::Value when,std::string const& sep);
|
|
||||||
|
|
||||||
Property* Get_prop(int index);
|
|
||||||
int Get_int(std::string const& _propname) const;
|
|
||||||
const char* Get_string(std::string const& _propname) const;
|
|
||||||
bool Get_bool(std::string const& _propname) const;
|
|
||||||
Hex Get_hex(std::string const& _propname) const;
|
|
||||||
double Get_double(std::string const& _propname) const;
|
|
||||||
Prop_path* Get_path(std::string const& _propname) const;
|
|
||||||
Prop_multival* Get_multival(std::string const& _propname) const;
|
|
||||||
Prop_multival_remain* Get_multivalremain(std::string const& _propname) const;
|
|
||||||
void HandleInputline(std::string const& gegevens);
|
|
||||||
void PrintData(FILE* outfile) const;
|
|
||||||
virtual std::string GetPropValue(std::string const& _property) const;
|
|
||||||
//ExecuteDestroy should be here else the destroy functions use destroyed properties
|
|
||||||
virtual ~Section_prop();
|
|
||||||
};
|
|
||||||
|
|
||||||
class Prop_multival:public Property{
|
|
||||||
protected:
|
|
||||||
Section_prop* section;
|
|
||||||
std::string seperator;
|
|
||||||
void make_default_value();
|
|
||||||
public:
|
|
||||||
Prop_multival(std::string const& _propname, Changeable::Value when,std::string const& sep):Property(_propname,when), section(new Section_prop("")),seperator(sep) {
|
|
||||||
default_value = value = "";
|
|
||||||
}
|
|
||||||
Section_prop *GetSection() { return section; }
|
|
||||||
const Section_prop *GetSection() const { return section; }
|
|
||||||
virtual void SetValue(std::string const& input);
|
|
||||||
virtual const std::vector<Value>& GetValues() const;
|
|
||||||
~Prop_multival() { delete section; }
|
|
||||||
}; //value bevat totale string. setvalue zet elk van de sub properties en checked die.
|
|
||||||
|
|
||||||
class Prop_multival_remain:public Prop_multival{
|
|
||||||
public:
|
|
||||||
Prop_multival_remain(std::string const& _propname, Changeable::Value when,std::string const& sep):Prop_multival(_propname,when,sep){ }
|
|
||||||
|
|
||||||
virtual void SetValue(std::string const& input);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class Section_line: public Section{
|
|
||||||
public:
|
|
||||||
Section_line(std::string const& _sectionname):Section(_sectionname){}
|
|
||||||
~Section_line(){ExecuteDestroy(true);}
|
|
||||||
void HandleInputline(std::string const& gegevens);
|
|
||||||
void PrintData(FILE* outfile) const;
|
|
||||||
virtual std::string GetPropValue(std::string const& _property) const;
|
|
||||||
std::string data;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Module_base {
|
|
||||||
/* Base for all hardware and software "devices" */
|
|
||||||
protected:
|
|
||||||
Section* m_configuration;
|
|
||||||
public:
|
|
||||||
Module_base(Section* configuration){m_configuration=configuration;};
|
|
||||||
// Module_base(Section* configuration, SaveState* state) {};
|
|
||||||
virtual ~Module_base(){/*LOG_MSG("executed")*/;};//Destructors are required
|
|
||||||
/* Returns true if succesful.*/
|
|
||||||
virtual bool Change_Config(Section* /*newconfig*/) {return false;} ;
|
|
||||||
};
|
|
||||||
#endif
|
#endif
|
||||||
|
144
include/shell.h
144
include/shell.h
@ -1,144 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2002-2007 The DOSBox Team
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* $Id: shell.h,v 1.26 2009/03/23 10:55:35 qbix79 Exp $ */
|
|
||||||
|
|
||||||
#ifndef DOSBOX_SHELL_H
|
|
||||||
#define DOSBOX_SHELL_H
|
|
||||||
|
|
||||||
#include <ctype.h>
|
|
||||||
#ifndef DOSBOX_DOSBOX_H
|
|
||||||
#include "dosbox.h"
|
|
||||||
#endif
|
|
||||||
#ifndef DOSBOX_PROGRAMS_H
|
|
||||||
#include "programs.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <string>
|
|
||||||
#include <list>
|
|
||||||
|
|
||||||
#define CMD_MAXLINE 4096
|
|
||||||
#define CMD_MAXCMDS 20
|
|
||||||
#define CMD_OLDSIZE 4096
|
|
||||||
extern Bitu call_shellstop;
|
|
||||||
/* first_shell is used to add and delete stuff from the shell env
|
|
||||||
* by "external" programs. (config) */
|
|
||||||
extern Program * first_shell;
|
|
||||||
|
|
||||||
class DOS_Shell;
|
|
||||||
|
|
||||||
class BatchFile {
|
|
||||||
public:
|
|
||||||
BatchFile(DOS_Shell * host,char const* const name, char const * const cmd_line);
|
|
||||||
virtual ~BatchFile();
|
|
||||||
virtual bool ReadLine(char * line);
|
|
||||||
bool Goto(char * where);
|
|
||||||
void Shift(void);
|
|
||||||
Bit16u file_handle;
|
|
||||||
Bit32u location;
|
|
||||||
bool echo;
|
|
||||||
DOS_Shell * shell;
|
|
||||||
BatchFile * prev;
|
|
||||||
CommandLine * cmd;
|
|
||||||
};
|
|
||||||
|
|
||||||
class AutoexecEditor;
|
|
||||||
class DOS_Shell : public Program {
|
|
||||||
private:
|
|
||||||
friend class AutoexecEditor;
|
|
||||||
std::list<std::string> l_history, l_completion;
|
|
||||||
|
|
||||||
char *completion_start;
|
|
||||||
Bit16u completion_index;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
DOS_Shell();
|
|
||||||
|
|
||||||
void Run(void);
|
|
||||||
void RunInternal(void); //for command /C
|
|
||||||
/* A load of subfunctions */
|
|
||||||
void ParseLine(char * line);
|
|
||||||
Bitu GetRedirection(char *s, char **ifn, char **ofn,bool * append);
|
|
||||||
void InputCommand(char * line);
|
|
||||||
void ShowPrompt();
|
|
||||||
void DoCommand(char * cmd);
|
|
||||||
bool Execute(char * name,char * args);
|
|
||||||
/* Checks if it matches a hardware-property */
|
|
||||||
bool CheckConfig(char* cmd_in,char*line);
|
|
||||||
/* Some internal used functions */
|
|
||||||
char * Which(char * name);
|
|
||||||
/* Some supported commands */
|
|
||||||
void CMD_HELP(char * args);
|
|
||||||
void CMD_CLS(char * args);
|
|
||||||
void CMD_COPY(char * args);
|
|
||||||
void CMD_DIR(char * args);
|
|
||||||
void CMD_DELETE(char * args);
|
|
||||||
void CMD_ECHO(char * args);
|
|
||||||
void CMD_EXIT(char * args);
|
|
||||||
void CMD_MKDIR(char * args);
|
|
||||||
void CMD_CHDIR(char * args);
|
|
||||||
void CMD_RMDIR(char * args);
|
|
||||||
void CMD_SET(char * args);
|
|
||||||
void CMD_IF(char * args);
|
|
||||||
void CMD_GOTO(char * args);
|
|
||||||
void CMD_TYPE(char * args);
|
|
||||||
void CMD_REM(char * args);
|
|
||||||
void CMD_RENAME(char * args);
|
|
||||||
void CMD_CALL(char * args);
|
|
||||||
void SyntaxError(void);
|
|
||||||
void CMD_PAUSE(char * args);
|
|
||||||
void CMD_SUBST(char* args);
|
|
||||||
void CMD_LOADHIGH(char* args);
|
|
||||||
void CMD_CHOICE(char * args);
|
|
||||||
void CMD_ATTRIB(char * args);
|
|
||||||
void CMD_PATH(char * args);
|
|
||||||
void CMD_SHIFT(char * args);
|
|
||||||
void CMD_VER(char * args);
|
|
||||||
/* The shell's variables */
|
|
||||||
Bit16u input_handle;
|
|
||||||
BatchFile * bf;
|
|
||||||
bool echo;
|
|
||||||
bool exit;
|
|
||||||
bool call;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SHELL_Cmd {
|
|
||||||
const char * name; /* Command name*/
|
|
||||||
Bit32u flags; /* Flags about the command */
|
|
||||||
void (DOS_Shell::*handler)(char * args); /* Handler for this command */
|
|
||||||
const char * help; /* String with command help */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Object to manage lines in the autoexec.bat The lines get removed from
|
|
||||||
* the file if the object gets destroyed. The environment is updated
|
|
||||||
* as well if the line set a a variable */
|
|
||||||
class AutoexecObject{
|
|
||||||
private:
|
|
||||||
bool installed;
|
|
||||||
std::string buf;
|
|
||||||
public:
|
|
||||||
AutoexecObject():installed(false){ };
|
|
||||||
void Install(std::string const &in);
|
|
||||||
void InstallBefore(std::string const &in);
|
|
||||||
~AutoexecObject();
|
|
||||||
private:
|
|
||||||
void CreateAutoexec(void);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2007 The DOSBox Team
|
* Copyright (C) 2002 The DOSBox Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -9,52 +9,55 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Library General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: support.h,v 1.17 2009/04/25 16:25:03 harekiet Exp $ */
|
#if !defined __SUPPORT_H
|
||||||
|
#define __SUPPORT_H
|
||||||
|
|
||||||
#ifndef DOSBOX_SUPPORT_H
|
|
||||||
#define DOSBOX_SUPPORT_H
|
|
||||||
|
|
||||||
|
#include <dosbox.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <string>
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#ifndef DOSBOX_DOSBOX_H
|
|
||||||
#include "dosbox.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined (_MSC_VER) /* MS Visual C++ */
|
#if defined (_MSC_VER) /* MS Visual C++ */
|
||||||
#define strcasecmp(a,b) stricmp(a,b)
|
#define strcasecmp(a,b) stricmp(a,b)
|
||||||
#define strncasecmp(a,b,n) _strnicmp(a,b,n)
|
#define strncasecmp(a,b,n) _strnicmp(a,b,n)
|
||||||
|
// if (stricmp(name,devices[index]->name)==0) return index;
|
||||||
|
#else
|
||||||
|
//if (strcasecmp(name,devices[index]->name)==0) return index;
|
||||||
|
//#define nocasestrcmp(a,b) stricmp(a,b)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define safe_strncpy(a,b,n) do { strncpy((a),(b),(n)-1); (a)[(n)-1] = 0; } while (0)
|
|
||||||
|
|
||||||
#ifdef HAVE_STRINGS_H
|
|
||||||
#include <strings.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void strreplace(char * str,char o,char n);
|
void strreplace(char * str,char o,char n);
|
||||||
char *ltrim(char *str);
|
char *ltrim(char *str);
|
||||||
char *rtrim(char *str);
|
void rtrim(char * const str);
|
||||||
char *trim(char *str);
|
char *trim(char *str);
|
||||||
char * upcase(char * str);
|
|
||||||
char * lowcase(char * str);
|
|
||||||
|
|
||||||
bool ScanCMDBool(char * cmd,char const * const check);
|
bool wildcmp(char *wild, char *string);
|
||||||
|
|
||||||
|
bool ScanCMDBool(char * cmd,char * check);
|
||||||
char * ScanCMDRemain(char * cmd);
|
char * ScanCMDRemain(char * cmd);
|
||||||
char * StripWord(char *&cmd);
|
bool ScanCMDHex(char * cmd,char * check,Bits * result);
|
||||||
bool IsDecWord(char * word);
|
char * StripWord(char * cmd);
|
||||||
bool IsHexWord(char * word);
|
|
||||||
Bits ConvDecWord(char * word);
|
INLINE char * upcase(char * str) {
|
||||||
Bits ConvHexWord(char * word);
|
char * oldstr=str;
|
||||||
|
while (*str) *str++=toupper(*str);
|
||||||
|
return oldstr;
|
||||||
|
}
|
||||||
|
|
||||||
|
INLINE char * lowcase(char * str) {
|
||||||
|
char * oldstr=str;
|
||||||
|
while (*str) *str++=tolower(*str);
|
||||||
|
return oldstr;
|
||||||
|
}
|
||||||
|
|
||||||
void upcase(std::string &str);
|
|
||||||
void lowcase(std::string &str);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2007 The DOSBox Team
|
* Copyright (C) 2002 The DOSBox Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -9,30 +9,45 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Library General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef DOSBOX_TIMER_H
|
#ifndef _TIMER_H_
|
||||||
#define DOSBOX_TIMER_H
|
#define _TIMER_H_
|
||||||
|
|
||||||
/* underlying clock rate in HZ */
|
/* underlying clock rate in HZ */
|
||||||
#include <SDL.h>
|
#include <SDL/SDL.h>
|
||||||
|
|
||||||
#define PIT_TICK_RATE 1193182
|
|
||||||
|
|
||||||
|
extern Bit32u LastTicks;
|
||||||
#define GetTicks() SDL_GetTicks()
|
#define GetTicks() SDL_GetTicks()
|
||||||
|
|
||||||
typedef void (*TIMER_TickHandler)(void);
|
typedef void (*TIMER_TickHandler)(Bitu ticks);
|
||||||
|
typedef void (*TIMER_MicroHandler)(void);
|
||||||
|
typedef void (*TIMER_DelayHandler)(void);
|
||||||
|
|
||||||
|
typedef void TIMER_Block;
|
||||||
|
|
||||||
|
|
||||||
/* Register a function that gets called everytime if 1 or more ticks pass */
|
/* Register a function that gets called everytime if 1 or more ticks pass */
|
||||||
void TIMER_AddTickHandler(TIMER_TickHandler handler);
|
TIMER_Block * TIMER_RegisterTickHandler(TIMER_TickHandler handler);
|
||||||
void TIMER_DelTickHandler(TIMER_TickHandler handler);
|
/* Register a function to be called every x microseconds */
|
||||||
|
TIMER_Block * TIMER_RegisterMicroHandler(TIMER_MicroHandler handler,Bitu micro);
|
||||||
|
/* Register a function to be called once after x microseconds */
|
||||||
|
TIMER_Block * TIMER_RegisterDelayHandler(TIMER_DelayHandler handler,Bitu delay);
|
||||||
|
|
||||||
|
/* Set the microseconds value to a new value */
|
||||||
|
void TIMER_SetNewMicro(TIMER_Block * block,Bitu micro);
|
||||||
|
|
||||||
|
|
||||||
|
/* This function should be called very often to support very high res timers
|
||||||
|
Although with the new timer code it doesn't matter that much */
|
||||||
|
void TIMER_CheckPIT(void);
|
||||||
|
/* This will add ms ticks to support the timer handlers */
|
||||||
|
void TIMER_AddTicks(Bit32u ticks);
|
||||||
|
|
||||||
/* This will add 1 milliscond to all timers */
|
|
||||||
void TIMER_AddTick(void);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
509
include/vga.h
509
include/vga.h
@ -1,509 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2002-2009 The DOSBox Team
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* $Id: vga.h,v 1.46 2009/03/15 11:28:34 c2woody Exp $ */
|
|
||||||
|
|
||||||
#ifndef DOSBOX_VGA_H
|
|
||||||
#define DOSBOX_VGA_H
|
|
||||||
|
|
||||||
#ifndef DOSBOX_DOSBOX_H
|
|
||||||
#include "dosbox.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//Don't enable keeping changes and mapping lfb probably...
|
|
||||||
#define VGA_LFB_MAPPED
|
|
||||||
//#define VGA_KEEP_CHANGES
|
|
||||||
#define VGA_CHANGE_SHIFT 9
|
|
||||||
|
|
||||||
class PageHandler;
|
|
||||||
|
|
||||||
|
|
||||||
enum VGAModes {
|
|
||||||
M_CGA2, M_CGA4,
|
|
||||||
M_EGA, M_VGA,
|
|
||||||
M_LIN4, M_LIN8, M_LIN15, M_LIN16, M_LIN32,
|
|
||||||
M_TEXT,
|
|
||||||
M_HERC_GFX, M_HERC_TEXT,
|
|
||||||
M_CGA16, M_TANDY2, M_TANDY4, M_TANDY16, M_TANDY_TEXT,
|
|
||||||
M_ERROR
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#define CLK_25 25175
|
|
||||||
#define CLK_28 28322
|
|
||||||
|
|
||||||
#define MIN_VCO 180000
|
|
||||||
#define MAX_VCO 360000
|
|
||||||
|
|
||||||
#define S3_CLOCK_REF 14318 /* KHz */
|
|
||||||
#define S3_CLOCK(_M,_N,_R) ((S3_CLOCK_REF * ((_M) + 2)) / (((_N) + 2) * (1 << (_R))))
|
|
||||||
#define S3_MAX_CLOCK 150000 /* KHz */
|
|
||||||
|
|
||||||
#define S3_XGA_1024 0x00
|
|
||||||
#define S3_XGA_1152 0x01
|
|
||||||
#define S3_XGA_640 0x40
|
|
||||||
#define S3_XGA_800 0x80
|
|
||||||
#define S3_XGA_1280 0xc0
|
|
||||||
#define S3_XGA_WMASK (S3_XGA_640|S3_XGA_800|S3_XGA_1024|S3_XGA_1152|S3_XGA_1280)
|
|
||||||
|
|
||||||
#define S3_XGA_8BPP 0x00
|
|
||||||
#define S3_XGA_16BPP 0x10
|
|
||||||
#define S3_XGA_32BPP 0x30
|
|
||||||
#define S3_XGA_CMASK (S3_XGA_8BPP|S3_XGA_16BPP|S3_XGA_32BPP)
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
bool attrindex;
|
|
||||||
} VGA_Internal;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
/* Memory handlers */
|
|
||||||
Bitu mh_mask;
|
|
||||||
|
|
||||||
/* Video drawing */
|
|
||||||
Bitu display_start;
|
|
||||||
Bitu real_start;
|
|
||||||
bool retrace; /* A retrace is active */
|
|
||||||
Bitu scan_len;
|
|
||||||
Bitu cursor_start;
|
|
||||||
|
|
||||||
/* Some other screen related variables */
|
|
||||||
Bitu line_compare;
|
|
||||||
bool chained; /* Enable or Disabled Chain 4 Mode */
|
|
||||||
bool compatible_chain4;
|
|
||||||
|
|
||||||
/* Pixel Scrolling */
|
|
||||||
Bit8u pel_panning; /* Amount of pixels to skip when starting horizontal line */
|
|
||||||
Bit8u hlines_skip;
|
|
||||||
Bit8u bytes_skip;
|
|
||||||
Bit8u addr_shift;
|
|
||||||
|
|
||||||
/* Specific stuff memory write/read handling */
|
|
||||||
|
|
||||||
Bit8u read_mode;
|
|
||||||
Bit8u write_mode;
|
|
||||||
Bit8u read_map_select;
|
|
||||||
Bit8u color_dont_care;
|
|
||||||
Bit8u color_compare;
|
|
||||||
Bit8u data_rotate;
|
|
||||||
Bit8u raster_op;
|
|
||||||
|
|
||||||
Bit32u full_bit_mask;
|
|
||||||
Bit32u full_map_mask;
|
|
||||||
Bit32u full_not_map_mask;
|
|
||||||
Bit32u full_set_reset;
|
|
||||||
Bit32u full_not_enable_set_reset;
|
|
||||||
Bit32u full_enable_set_reset;
|
|
||||||
Bit32u full_enable_and_set_reset;
|
|
||||||
} VGA_Config;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
bool resizing;
|
|
||||||
Bitu width;
|
|
||||||
Bitu height;
|
|
||||||
Bitu blocks;
|
|
||||||
Bitu address;
|
|
||||||
Bitu panning;
|
|
||||||
Bitu bytes_skip;
|
|
||||||
Bit8u *linear_base;
|
|
||||||
Bitu linear_mask;
|
|
||||||
Bitu address_add;
|
|
||||||
Bitu line_length;
|
|
||||||
Bitu address_line_total;
|
|
||||||
Bitu address_line;
|
|
||||||
Bitu lines_total;
|
|
||||||
Bitu lines_done;
|
|
||||||
Bitu lines_scaled;
|
|
||||||
Bitu split_line;
|
|
||||||
Bitu parts_total;
|
|
||||||
Bitu parts_lines;
|
|
||||||
Bitu parts_left;
|
|
||||||
Bitu byte_panning_shift;
|
|
||||||
struct {
|
|
||||||
double framestart;
|
|
||||||
double vrstart, vrend; // V-retrace
|
|
||||||
double hrstart, hrend; // H-retrace
|
|
||||||
double hblkstart, hblkend; // H-blanking
|
|
||||||
double vblkstart, vblkend; // V-Blanking
|
|
||||||
double vdend, vtotal;
|
|
||||||
double hdend, htotal;
|
|
||||||
double parts;
|
|
||||||
} delay;
|
|
||||||
double aspect_ratio;
|
|
||||||
bool double_scan;
|
|
||||||
bool doublewidth,doubleheight;
|
|
||||||
Bit8u font[64*1024];
|
|
||||||
Bit8u * font_tables[2];
|
|
||||||
Bitu blinking;
|
|
||||||
struct {
|
|
||||||
Bitu address;
|
|
||||||
Bit8u sline,eline;
|
|
||||||
Bit8u count,delay;
|
|
||||||
Bit8u enabled;
|
|
||||||
} cursor;
|
|
||||||
bool vret_triggered;
|
|
||||||
} VGA_Draw;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
Bit8u curmode;
|
|
||||||
Bit16u originx, originy;
|
|
||||||
Bit8u fstackpos, bstackpos;
|
|
||||||
Bit8u forestack[3];
|
|
||||||
Bit8u backstack[3];
|
|
||||||
Bit16u startaddr;
|
|
||||||
Bit8u posx, posy;
|
|
||||||
Bit8u mc[64][64];
|
|
||||||
} VGA_HWCURSOR;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
Bit8u reg_lock1;
|
|
||||||
Bit8u reg_lock2;
|
|
||||||
Bit8u reg_31;
|
|
||||||
Bit8u reg_35;
|
|
||||||
Bit8u reg_36; // RAM size
|
|
||||||
Bit8u reg_3a; // 4/8/doublepixel bit in there
|
|
||||||
Bit8u reg_40; // 8415/A functionality register
|
|
||||||
Bit8u reg_41; // BIOS flags
|
|
||||||
Bit8u reg_43;
|
|
||||||
Bit8u reg_45; // Hardware graphics cursor
|
|
||||||
Bit8u reg_50;
|
|
||||||
Bit8u reg_51;
|
|
||||||
Bit8u reg_52;
|
|
||||||
Bit8u reg_55;
|
|
||||||
Bit8u reg_58;
|
|
||||||
Bit8u reg_6b; // LFB BIOS scratchpad
|
|
||||||
Bit8u ex_hor_overflow;
|
|
||||||
Bit8u ex_ver_overflow;
|
|
||||||
Bit16u la_window;
|
|
||||||
Bit8u misc_control_2;
|
|
||||||
Bit8u ext_mem_ctrl;
|
|
||||||
Bitu xga_screen_width;
|
|
||||||
VGAModes xga_color_mode;
|
|
||||||
struct {
|
|
||||||
Bit8u r;
|
|
||||||
Bit8u n;
|
|
||||||
Bit8u m;
|
|
||||||
} clk[4],mclk;
|
|
||||||
struct {
|
|
||||||
Bit8u lock;
|
|
||||||
Bit8u cmd;
|
|
||||||
} pll;
|
|
||||||
VGA_HWCURSOR hgc;
|
|
||||||
} VGA_S3;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
Bit8u mode_control;
|
|
||||||
Bit8u enable_bits;
|
|
||||||
} VGA_HERC;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
Bit8u index;
|
|
||||||
Bit8u htotal;
|
|
||||||
Bit8u hdend;
|
|
||||||
Bit8u hsyncp;
|
|
||||||
Bit8u syncw;
|
|
||||||
Bit8u vtotal;
|
|
||||||
Bit8u vdend;
|
|
||||||
Bit8u vadjust;
|
|
||||||
Bit8u vsyncp;
|
|
||||||
Bit8u vsyncw;
|
|
||||||
Bit8u max_scanline;
|
|
||||||
Bit8u lpen_low, lpen_high;
|
|
||||||
Bit8u cursor_start;
|
|
||||||
Bit8u cursor_end;
|
|
||||||
} VGA_OTHER;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
Bit8u pcjr_flipflop;
|
|
||||||
Bit8u mode_control;
|
|
||||||
Bit8u color_select;
|
|
||||||
Bit8u disp_bank;
|
|
||||||
Bit8u reg_index;
|
|
||||||
Bit8u gfx_control;
|
|
||||||
Bit8u palette_mask;
|
|
||||||
Bit8u extended_ram;
|
|
||||||
Bit8u border_color;
|
|
||||||
Bit8u line_mask, line_shift;
|
|
||||||
Bit8u draw_bank, mem_bank;
|
|
||||||
Bit8u *draw_base, *mem_base;
|
|
||||||
Bitu addr_mask;
|
|
||||||
} VGA_TANDY;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
Bit8u index;
|
|
||||||
Bit8u reset;
|
|
||||||
Bit8u clocking_mode;
|
|
||||||
Bit8u map_mask;
|
|
||||||
Bit8u character_map_select;
|
|
||||||
Bit8u memory_mode;
|
|
||||||
} VGA_Seq;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
Bit8u palette[16];
|
|
||||||
Bit8u mode_control;
|
|
||||||
Bit8u horizontal_pel_panning;
|
|
||||||
Bit8u overscan_color;
|
|
||||||
Bit8u color_plane_enable;
|
|
||||||
Bit8u color_select;
|
|
||||||
Bit8u index;
|
|
||||||
Bit8u enabled;
|
|
||||||
} VGA_Attr;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
Bit8u horizontal_total;
|
|
||||||
Bit8u horizontal_display_end;
|
|
||||||
Bit8u start_horizontal_blanking;
|
|
||||||
Bit8u end_horizontal_blanking;
|
|
||||||
Bit8u start_horizontal_retrace;
|
|
||||||
Bit8u end_horizontal_retrace;
|
|
||||||
Bit8u vertical_total;
|
|
||||||
Bit8u overflow;
|
|
||||||
Bit8u preset_row_scan;
|
|
||||||
Bit8u maximum_scan_line;
|
|
||||||
Bit8u cursor_start;
|
|
||||||
Bit8u cursor_end;
|
|
||||||
Bit8u start_address_high;
|
|
||||||
Bit8u start_address_low;
|
|
||||||
Bit8u cursor_location_high;
|
|
||||||
Bit8u cursor_location_low;
|
|
||||||
Bit8u vertical_retrace_start;
|
|
||||||
Bit8u vertical_retrace_end;
|
|
||||||
Bit8u vertical_display_end;
|
|
||||||
Bit8u offset;
|
|
||||||
Bit8u underline_location;
|
|
||||||
Bit8u start_vertical_blanking;
|
|
||||||
Bit8u end_vertical_blanking;
|
|
||||||
Bit8u mode_control;
|
|
||||||
Bit8u line_compare;
|
|
||||||
|
|
||||||
Bit8u index;
|
|
||||||
bool read_only;
|
|
||||||
} VGA_Crtc;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
Bit8u index;
|
|
||||||
Bit8u set_reset;
|
|
||||||
Bit8u enable_set_reset;
|
|
||||||
Bit8u color_compare;
|
|
||||||
Bit8u data_rotate;
|
|
||||||
Bit8u read_map_select;
|
|
||||||
Bit8u mode;
|
|
||||||
Bit8u miscellaneous;
|
|
||||||
Bit8u color_dont_care;
|
|
||||||
Bit8u bit_mask;
|
|
||||||
} VGA_Gfx;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
Bit8u red;
|
|
||||||
Bit8u green;
|
|
||||||
Bit8u blue;
|
|
||||||
} RGBEntry;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
Bit8u bits; /* DAC bits, usually 6 or 8 */
|
|
||||||
Bit8u pel_mask;
|
|
||||||
Bit8u pel_index;
|
|
||||||
Bit8u state;
|
|
||||||
Bit8u write_index;
|
|
||||||
Bit8u read_index;
|
|
||||||
Bitu first_changed;
|
|
||||||
Bit8u combine[16];
|
|
||||||
RGBEntry rgb[0x100];
|
|
||||||
Bit16u xlat16[256];
|
|
||||||
} VGA_Dac;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
Bitu readStart, writeStart;
|
|
||||||
Bitu bankMask;
|
|
||||||
Bitu bank_read_full;
|
|
||||||
Bitu bank_write_full;
|
|
||||||
Bit8u bank_read;
|
|
||||||
Bit8u bank_write;
|
|
||||||
Bitu bank_size;
|
|
||||||
} VGA_SVGA;
|
|
||||||
|
|
||||||
typedef union {
|
|
||||||
Bit32u d;
|
|
||||||
Bit8u b[4];
|
|
||||||
} VGA_Latch;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
Bit8u* linear;
|
|
||||||
Bit8u* linear_orgptr;
|
|
||||||
} VGA_Memory;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
//Add a few more just to be safe
|
|
||||||
Bit8u* map; /* allocated dynamically: [(VGA_MEMORY >> VGA_CHANGE_SHIFT) + 32] */
|
|
||||||
Bit8u checkMask, frame, writeMask;
|
|
||||||
bool active;
|
|
||||||
Bit32u clearMask;
|
|
||||||
Bit32u start, last;
|
|
||||||
Bit32u lastAddress;
|
|
||||||
} VGA_Changes;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
Bit32u page;
|
|
||||||
Bit32u addr;
|
|
||||||
Bit32u mask;
|
|
||||||
PageHandler *handler;
|
|
||||||
} VGA_LFB;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
VGAModes mode; /* The mode the vga system is in */
|
|
||||||
VGAModes lastmode;
|
|
||||||
Bits screenflip;
|
|
||||||
Bit8u misc_output;
|
|
||||||
VGA_Draw draw;
|
|
||||||
VGA_Config config;
|
|
||||||
VGA_Internal internal;
|
|
||||||
/* Internal module groups */
|
|
||||||
VGA_Seq seq;
|
|
||||||
VGA_Attr attr;
|
|
||||||
VGA_Crtc crtc;
|
|
||||||
VGA_Gfx gfx;
|
|
||||||
VGA_Dac dac;
|
|
||||||
VGA_Latch latch;
|
|
||||||
VGA_S3 s3;
|
|
||||||
VGA_SVGA svga;
|
|
||||||
VGA_HERC herc;
|
|
||||||
VGA_TANDY tandy;
|
|
||||||
VGA_OTHER other;
|
|
||||||
VGA_Memory mem;
|
|
||||||
Bit32u vmemwrap; /* this is assumed to be power of 2 */
|
|
||||||
Bit8u* fastmem; /* memory for fast (usually 16-color) rendering, always twice as big as vmemsize */
|
|
||||||
Bit8u* fastmem_orgptr;
|
|
||||||
Bit32u vmemsize;
|
|
||||||
#ifdef VGA_KEEP_CHANGES
|
|
||||||
VGA_Changes changes;
|
|
||||||
#endif
|
|
||||||
VGA_LFB lfb;
|
|
||||||
} VGA_Type;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Functions for different resolutions */
|
|
||||||
void VGA_SetMode(VGAModes mode);
|
|
||||||
void VGA_DetermineMode(void);
|
|
||||||
void VGA_SetupHandlers(void);
|
|
||||||
void VGA_StartResize(Bitu delay=50);
|
|
||||||
void VGA_SetupDrawing(Bitu val);
|
|
||||||
void VGA_CheckScanLength(void);
|
|
||||||
void VGA_ChangedBank(void);
|
|
||||||
|
|
||||||
/* Some DAC/Attribute functions */
|
|
||||||
void VGA_DAC_CombineColor(Bit8u attr,Bit8u pal);
|
|
||||||
void VGA_DAC_SetEntry(Bitu entry,Bit8u red,Bit8u green,Bit8u blue);
|
|
||||||
void VGA_ATTR_SetPalette(Bit8u index,Bit8u val);
|
|
||||||
|
|
||||||
/* The VGA Subfunction startups */
|
|
||||||
void VGA_SetupAttr(void);
|
|
||||||
void VGA_SetupMemory(Section* sec);
|
|
||||||
void VGA_SetupDAC(void);
|
|
||||||
void VGA_SetupCRTC(void);
|
|
||||||
void VGA_SetupMisc(void);
|
|
||||||
void VGA_SetupGFX(void);
|
|
||||||
void VGA_SetupSEQ(void);
|
|
||||||
void VGA_SetupOther(void);
|
|
||||||
void VGA_SetupXGA(void);
|
|
||||||
|
|
||||||
/* Some Support Functions */
|
|
||||||
void VGA_SetClock(Bitu which,Bitu target);
|
|
||||||
void VGA_DACSetEntirePalette(void);
|
|
||||||
void VGA_StartRetrace(void);
|
|
||||||
void VGA_StartUpdateLFB(void);
|
|
||||||
void VGA_SetBlinking(Bitu enabled);
|
|
||||||
void VGA_SetCGA2Table(Bit8u val0,Bit8u val1);
|
|
||||||
void VGA_SetCGA4Table(Bit8u val0,Bit8u val1,Bit8u val2,Bit8u val3);
|
|
||||||
void VGA_ActivateHardwareCursor(void);
|
|
||||||
void VGA_KillDrawing(void);
|
|
||||||
|
|
||||||
extern VGA_Type vga;
|
|
||||||
|
|
||||||
/* Support for modular SVGA implementation */
|
|
||||||
/* Video mode extra data to be passed to FinishSetMode_SVGA().
|
|
||||||
This structure will be in flux until all drivers (including S3)
|
|
||||||
are properly separated. Right now it contains only three overflow
|
|
||||||
fields in S3 format and relies on drivers re-interpreting those.
|
|
||||||
For reference:
|
|
||||||
ver_overflow:X|line_comp10|X|vretrace10|X|vbstart10|vdispend10|vtotal10
|
|
||||||
hor_overflow:X|X|X|hretrace8|X|hblank8|hdispend8|htotal8
|
|
||||||
offset is not currently used by drivers (useful only for S3 itself)
|
|
||||||
It also contains basic int10 mode data - number, vtotal, htotal
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
Bit8u ver_overflow;
|
|
||||||
Bit8u hor_overflow;
|
|
||||||
Bitu offset;
|
|
||||||
Bitu modeNo;
|
|
||||||
Bitu htotal;
|
|
||||||
Bitu vtotal;
|
|
||||||
} VGA_ModeExtraData;
|
|
||||||
|
|
||||||
// Vector function prototypes
|
|
||||||
typedef void (*tWritePort)(Bitu reg,Bitu val,Bitu iolen);
|
|
||||||
typedef Bitu (*tReadPort)(Bitu reg,Bitu iolen);
|
|
||||||
typedef void (*tFinishSetMode)(Bitu crtc_base, VGA_ModeExtraData* modeData);
|
|
||||||
typedef void (*tDetermineMode)();
|
|
||||||
typedef void (*tSetClock)(Bitu which,Bitu target);
|
|
||||||
typedef Bitu (*tGetClock)();
|
|
||||||
typedef bool (*tHWCursorActive)();
|
|
||||||
typedef bool (*tAcceptsMode)(Bitu modeNo);
|
|
||||||
|
|
||||||
struct SVGA_Driver {
|
|
||||||
tWritePort write_p3d5;
|
|
||||||
tReadPort read_p3d5;
|
|
||||||
tWritePort write_p3c5;
|
|
||||||
tReadPort read_p3c5;
|
|
||||||
tWritePort write_p3c0;
|
|
||||||
tReadPort read_p3c1;
|
|
||||||
tWritePort write_p3cf;
|
|
||||||
tReadPort read_p3cf;
|
|
||||||
|
|
||||||
tFinishSetMode set_video_mode;
|
|
||||||
tDetermineMode determine_mode;
|
|
||||||
tSetClock set_clock;
|
|
||||||
tGetClock get_clock;
|
|
||||||
tHWCursorActive hardware_cursor_active;
|
|
||||||
tAcceptsMode accepts_mode;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern SVGA_Driver svga;
|
|
||||||
|
|
||||||
void SVGA_Setup_S3Trio(void);
|
|
||||||
void SVGA_Setup_TsengET4K(void);
|
|
||||||
void SVGA_Setup_TsengET3K(void);
|
|
||||||
void SVGA_Setup_ParadisePVGA1A(void);
|
|
||||||
void SVGA_Setup_Driver(void);
|
|
||||||
|
|
||||||
// Amount of video memory required for a mode, implemented in int10_modes.cpp
|
|
||||||
Bitu VideoModeMemSize(Bitu mode);
|
|
||||||
|
|
||||||
extern Bit32u ExpandTable[256];
|
|
||||||
extern Bit32u FillTable[16];
|
|
||||||
extern Bit32u CGA_2_Table[16];
|
|
||||||
extern Bit32u CGA_4_Table[256];
|
|
||||||
extern Bit32u CGA_4_HiRes_Table[256];
|
|
||||||
extern Bit32u CGA_16_Table[256];
|
|
||||||
extern Bit32u TXT_Font_Table[16];
|
|
||||||
extern Bit32u TXT_FG_Table[16];
|
|
||||||
extern Bit32u TXT_BG_Table[16];
|
|
||||||
extern Bit32u Expand16Table[4][16];
|
|
||||||
extern Bit32u Expand16BigTable[0x10000];
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2008 The DOSBox Team
|
* Copyright (C) 2002 The DOSBox Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -9,27 +9,19 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Library General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: video.h,v 1.25 2008/08/24 16:43:06 qbix79 Exp $ */
|
#ifndef __VIDEO_H
|
||||||
|
#define __VIDEO_H
|
||||||
|
|
||||||
#ifndef DOSBOX_VIDEO_H
|
typedef void (GFX_DrawHandler)(Bit8u * vidstart);
|
||||||
#define DOSBOX_VIDEO_H
|
/* Used to reply to the renderer what size to set */
|
||||||
|
typedef void (GFX_ResizeHandler)(Bitu * width,Bitu * height);
|
||||||
#define REDUCE_JOYSTICK_POLLING
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
GFX_CallBackReset,
|
|
||||||
GFX_CallBackStop,
|
|
||||||
GFX_CallBackRedraw
|
|
||||||
} GFX_CallBackFunctions_t;
|
|
||||||
|
|
||||||
typedef void (*GFX_CallBack_t)( GFX_CallBackFunctions_t function );
|
|
||||||
|
|
||||||
struct GFX_PalEntry {
|
struct GFX_PalEntry {
|
||||||
Bit8u r;
|
Bit8u r;
|
||||||
@ -38,48 +30,21 @@ struct GFX_PalEntry {
|
|||||||
Bit8u unused;
|
Bit8u unused;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define GFX_CAN_8 0x0001
|
struct GFX_Info {
|
||||||
#define GFX_CAN_15 0x0002
|
Bitu width,height,bpp,pitch;
|
||||||
#define GFX_CAN_16 0x0004
|
};
|
||||||
#define GFX_CAN_32 0x0008
|
|
||||||
|
|
||||||
#define GFX_LOVE_8 0x0010
|
extern GFX_Info gfx_info;
|
||||||
#define GFX_LOVE_15 0x0020
|
|
||||||
#define GFX_LOVE_16 0x0040
|
|
||||||
#define GFX_LOVE_32 0x0080
|
|
||||||
|
|
||||||
#define GFX_RGBONLY 0x0100
|
|
||||||
|
|
||||||
#define GFX_SCALING 0x1000
|
|
||||||
#define GFX_HARDWARE 0x2000
|
|
||||||
|
|
||||||
#define GFX_CAN_RANDOM 0x4000 //If the interface can also do random access surface
|
|
||||||
|
|
||||||
void GFX_Events(void);
|
void GFX_Events(void);
|
||||||
void GFX_SetPalette(Bitu start,Bitu count,GFX_PalEntry * entries);
|
void GFX_SetPalette(Bitu start,Bitu count,GFX_PalEntry * entries);
|
||||||
Bitu GFX_GetBestMode(Bitu flags);
|
void GFX_SetDrawHandler(GFX_DrawHandler * handler);
|
||||||
Bitu GFX_GetRGB(Bit8u red,Bit8u green,Bit8u blue);
|
void GFX_Resize(Bitu width,Bitu height,Bitu bpp,GFX_ResizeHandler * resize);
|
||||||
Bitu GFX_SetSize(Bitu width,Bitu height,Bitu flags,double scalex,double scaley,GFX_CallBack_t cb);
|
|
||||||
|
|
||||||
void GFX_ResetScreen(void);
|
|
||||||
void GFX_Start(void);
|
void GFX_Start(void);
|
||||||
void GFX_Stop(void);
|
void GFX_Stop(void);
|
||||||
void GFX_SwitchFullScreen(void);
|
void GFX_SwitchFullScreen(void);
|
||||||
bool GFX_StartUpdate(Bit8u * & pixels,Bitu & pitch);
|
|
||||||
void GFX_EndUpdate( const Bit16u *changedLines );
|
|
||||||
void GFX_GetSize(int &width, int &height, bool &fullscreen);
|
|
||||||
void GFX_LosingFocus(void);
|
|
||||||
|
|
||||||
#if defined (WIN32)
|
|
||||||
bool GFX_SDLUsingWinDIB(void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined (REDUCE_JOYSTICK_POLLING)
|
|
||||||
void MAPPER_UpdateJoysticks(void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Mouse related */
|
|
||||||
void GFX_CaptureMouse(void);
|
|
||||||
extern bool mouselocked; //true if mouse is confined to window
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
251
install-sh
Normal file
251
install-sh
Normal file
@ -0,0 +1,251 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# install - install a program, script, or datafile
|
||||||
|
# This comes from X11R5 (mit/util/scripts/install.sh).
|
||||||
|
#
|
||||||
|
# Copyright 1991 by the Massachusetts Institute of Technology
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, distribute, and sell this software and its
|
||||||
|
# documentation for any purpose is hereby granted without fee, provided that
|
||||||
|
# the above copyright notice appear in all copies and that both that
|
||||||
|
# copyright notice and this permission notice appear in supporting
|
||||||
|
# documentation, and that the name of M.I.T. not be used in advertising or
|
||||||
|
# publicity pertaining to distribution of the software without specific,
|
||||||
|
# written prior permission. M.I.T. makes no representations about the
|
||||||
|
# suitability of this software for any purpose. It is provided "as is"
|
||||||
|
# without express or implied warranty.
|
||||||
|
#
|
||||||
|
# Calling this script install-sh is preferred over install.sh, to prevent
|
||||||
|
# `make' implicit rules from creating a file called install from it
|
||||||
|
# when there is no Makefile.
|
||||||
|
#
|
||||||
|
# This script is compatible with the BSD install script, but was written
|
||||||
|
# from scratch. It can only install one file at a time, a restriction
|
||||||
|
# shared with many OS's install programs.
|
||||||
|
|
||||||
|
|
||||||
|
# set DOITPROG to echo to test this script
|
||||||
|
|
||||||
|
# Don't use :- since 4.3BSD and earlier shells don't like it.
|
||||||
|
doit="${DOITPROG-}"
|
||||||
|
|
||||||
|
|
||||||
|
# put in absolute paths if you don't have them in your path; or use env. vars.
|
||||||
|
|
||||||
|
mvprog="${MVPROG-mv}"
|
||||||
|
cpprog="${CPPROG-cp}"
|
||||||
|
chmodprog="${CHMODPROG-chmod}"
|
||||||
|
chownprog="${CHOWNPROG-chown}"
|
||||||
|
chgrpprog="${CHGRPPROG-chgrp}"
|
||||||
|
stripprog="${STRIPPROG-strip}"
|
||||||
|
rmprog="${RMPROG-rm}"
|
||||||
|
mkdirprog="${MKDIRPROG-mkdir}"
|
||||||
|
|
||||||
|
transformbasename=""
|
||||||
|
transform_arg=""
|
||||||
|
instcmd="$mvprog"
|
||||||
|
chmodcmd="$chmodprog 0755"
|
||||||
|
chowncmd=""
|
||||||
|
chgrpcmd=""
|
||||||
|
stripcmd=""
|
||||||
|
rmcmd="$rmprog -f"
|
||||||
|
mvcmd="$mvprog"
|
||||||
|
src=""
|
||||||
|
dst=""
|
||||||
|
dir_arg=""
|
||||||
|
|
||||||
|
while [ x"$1" != x ]; do
|
||||||
|
case $1 in
|
||||||
|
-c) instcmd="$cpprog"
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-d) dir_arg=true
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-m) chmodcmd="$chmodprog $2"
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-o) chowncmd="$chownprog $2"
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-g) chgrpcmd="$chgrpprog $2"
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-s) stripcmd="$stripprog"
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
|
||||||
|
*) if [ x"$src" = x ]
|
||||||
|
then
|
||||||
|
src=$1
|
||||||
|
else
|
||||||
|
# this colon is to work around a 386BSD /bin/sh bug
|
||||||
|
:
|
||||||
|
dst=$1
|
||||||
|
fi
|
||||||
|
shift
|
||||||
|
continue;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ x"$src" = x ]
|
||||||
|
then
|
||||||
|
echo "install: no input file specified"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
:
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ x"$dir_arg" != x ]; then
|
||||||
|
dst=$src
|
||||||
|
src=""
|
||||||
|
|
||||||
|
if [ -d $dst ]; then
|
||||||
|
instcmd=:
|
||||||
|
chmodcmd=""
|
||||||
|
else
|
||||||
|
instcmd=$mkdirprog
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
|
||||||
|
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
|
||||||
|
# might cause directories to be created, which would be especially bad
|
||||||
|
# if $src (and thus $dsttmp) contains '*'.
|
||||||
|
|
||||||
|
if [ -f $src -o -d $src ]
|
||||||
|
then
|
||||||
|
:
|
||||||
|
else
|
||||||
|
echo "install: $src does not exist"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ x"$dst" = x ]
|
||||||
|
then
|
||||||
|
echo "install: no destination specified"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
:
|
||||||
|
fi
|
||||||
|
|
||||||
|
# If destination is a directory, append the input filename; if your system
|
||||||
|
# does not like double slashes in filenames, you may need to add some logic
|
||||||
|
|
||||||
|
if [ -d $dst ]
|
||||||
|
then
|
||||||
|
dst="$dst"/`basename $src`
|
||||||
|
else
|
||||||
|
:
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
## this sed command emulates the dirname command
|
||||||
|
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
|
||||||
|
|
||||||
|
# Make sure that the destination directory exists.
|
||||||
|
# this part is taken from Noah Friedman's mkinstalldirs script
|
||||||
|
|
||||||
|
# Skip lots of stat calls in the usual case.
|
||||||
|
if [ ! -d "$dstdir" ]; then
|
||||||
|
defaultIFS='
|
||||||
|
'
|
||||||
|
IFS="${IFS-${defaultIFS}}"
|
||||||
|
|
||||||
|
oIFS="${IFS}"
|
||||||
|
# Some sh's can't handle IFS=/ for some reason.
|
||||||
|
IFS='%'
|
||||||
|
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
|
||||||
|
IFS="${oIFS}"
|
||||||
|
|
||||||
|
pathcomp=''
|
||||||
|
|
||||||
|
while [ $# -ne 0 ] ; do
|
||||||
|
pathcomp="${pathcomp}${1}"
|
||||||
|
shift
|
||||||
|
|
||||||
|
if [ ! -d "${pathcomp}" ] ;
|
||||||
|
then
|
||||||
|
$mkdirprog "${pathcomp}"
|
||||||
|
else
|
||||||
|
:
|
||||||
|
fi
|
||||||
|
|
||||||
|
pathcomp="${pathcomp}/"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ x"$dir_arg" != x ]
|
||||||
|
then
|
||||||
|
$doit $instcmd $dst &&
|
||||||
|
|
||||||
|
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else : ; fi &&
|
||||||
|
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else : ; fi &&
|
||||||
|
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else : ; fi &&
|
||||||
|
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else : ; fi
|
||||||
|
else
|
||||||
|
|
||||||
|
# If we're going to rename the final executable, determine the name now.
|
||||||
|
|
||||||
|
if [ x"$transformarg" = x ]
|
||||||
|
then
|
||||||
|
dstfile=`basename $dst`
|
||||||
|
else
|
||||||
|
dstfile=`basename $dst $transformbasename |
|
||||||
|
sed $transformarg`$transformbasename
|
||||||
|
fi
|
||||||
|
|
||||||
|
# don't allow the sed command to completely eliminate the filename
|
||||||
|
|
||||||
|
if [ x"$dstfile" = x ]
|
||||||
|
then
|
||||||
|
dstfile=`basename $dst`
|
||||||
|
else
|
||||||
|
:
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Make a temp file name in the proper directory.
|
||||||
|
|
||||||
|
dsttmp=$dstdir/#inst.$$#
|
||||||
|
|
||||||
|
# Move or copy the file name to the temp name
|
||||||
|
|
||||||
|
$doit $instcmd $src $dsttmp &&
|
||||||
|
|
||||||
|
trap "rm -f ${dsttmp}" 0 &&
|
||||||
|
|
||||||
|
# and set any options; do chmod last to preserve setuid bits
|
||||||
|
|
||||||
|
# If any of these fail, we abort the whole thing. If we want to
|
||||||
|
# ignore errors from any of these, just make sure not to ignore
|
||||||
|
# errors from the above "$doit $instcmd $src $dsttmp" command.
|
||||||
|
|
||||||
|
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else :;fi &&
|
||||||
|
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else :;fi &&
|
||||||
|
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else :;fi &&
|
||||||
|
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else :;fi &&
|
||||||
|
|
||||||
|
# Now rename the file to the real destination.
|
||||||
|
|
||||||
|
$doit $rmcmd -f $dstdir/$dstfile &&
|
||||||
|
$doit $mvcmd $dsttmp $dstdir/$dstfile
|
||||||
|
|
||||||
|
fi &&
|
||||||
|
|
||||||
|
|
||||||
|
exit 0
|
336
missing
Normal file
336
missing
Normal file
@ -0,0 +1,336 @@
|
|||||||
|
#! /bin/sh
|
||||||
|
# Common stub for a few missing GNU programs while installing.
|
||||||
|
# Copyright 1996, 1997, 1999, 2000 Free Software Foundation, Inc.
|
||||||
|
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
|
||||||
|
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
||||||
|
# 02111-1307, USA.
|
||||||
|
|
||||||
|
# As a special exception to the GNU General Public License, if you
|
||||||
|
# distribute this file as part of a program that contains a
|
||||||
|
# configuration script generated by Autoconf, you may include it under
|
||||||
|
# the same distribution terms that you use for the rest of that program.
|
||||||
|
|
||||||
|
if test $# -eq 0; then
|
||||||
|
echo 1>&2 "Try \`$0 --help' for more information"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
run=:
|
||||||
|
|
||||||
|
# In the cases where this matters, `missing' is being run in the
|
||||||
|
# srcdir already.
|
||||||
|
if test -f configure.ac; then
|
||||||
|
configure_ac=configure.ac
|
||||||
|
else
|
||||||
|
configure_ac=configure.in
|
||||||
|
fi
|
||||||
|
|
||||||
|
case "$1" in
|
||||||
|
--run)
|
||||||
|
# Try to run requested program, and just exit if it succeeds.
|
||||||
|
run=
|
||||||
|
shift
|
||||||
|
"$@" && exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# If it does not exist, or fails to run (possibly an outdated version),
|
||||||
|
# try to emulate it.
|
||||||
|
case "$1" in
|
||||||
|
|
||||||
|
-h|--h|--he|--hel|--help)
|
||||||
|
echo "\
|
||||||
|
$0 [OPTION]... PROGRAM [ARGUMENT]...
|
||||||
|
|
||||||
|
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
|
||||||
|
error status if there is no known handling for PROGRAM.
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-h, --help display this help and exit
|
||||||
|
-v, --version output version information and exit
|
||||||
|
--run try to run the given command, and emulate it if it fails
|
||||||
|
|
||||||
|
Supported PROGRAM values:
|
||||||
|
aclocal touch file \`aclocal.m4'
|
||||||
|
autoconf touch file \`configure'
|
||||||
|
autoheader touch file \`config.h.in'
|
||||||
|
automake touch all \`Makefile.in' files
|
||||||
|
bison create \`y.tab.[ch]', if possible, from existing .[ch]
|
||||||
|
flex create \`lex.yy.c', if possible, from existing .c
|
||||||
|
help2man touch the output file
|
||||||
|
lex create \`lex.yy.c', if possible, from existing .c
|
||||||
|
makeinfo touch the output file
|
||||||
|
tar try tar, gnutar, gtar, then tar without non-portable flags
|
||||||
|
yacc create \`y.tab.[ch]', if possible, from existing .[ch]"
|
||||||
|
;;
|
||||||
|
|
||||||
|
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
|
||||||
|
echo "missing 0.4 - GNU automake"
|
||||||
|
;;
|
||||||
|
|
||||||
|
-*)
|
||||||
|
echo 1>&2 "$0: Unknown \`$1' option"
|
||||||
|
echo 1>&2 "Try \`$0 --help' for more information"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
aclocal*)
|
||||||
|
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
|
||||||
|
# We have it, but it failed.
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo 1>&2 "\
|
||||||
|
WARNING: \`$1' is missing on your system. You should only need it if
|
||||||
|
you modified \`acinclude.m4' or \`${configure_ac}'. You might want
|
||||||
|
to install the \`Automake' and \`Perl' packages. Grab them from
|
||||||
|
any GNU archive site."
|
||||||
|
touch aclocal.m4
|
||||||
|
;;
|
||||||
|
|
||||||
|
autoconf)
|
||||||
|
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
|
||||||
|
# We have it, but it failed.
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo 1>&2 "\
|
||||||
|
WARNING: \`$1' is missing on your system. You should only need it if
|
||||||
|
you modified \`${configure_ac}'. You might want to install the
|
||||||
|
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
|
||||||
|
archive site."
|
||||||
|
touch configure
|
||||||
|
;;
|
||||||
|
|
||||||
|
autoheader)
|
||||||
|
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
|
||||||
|
# We have it, but it failed.
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo 1>&2 "\
|
||||||
|
WARNING: \`$1' is missing on your system. You should only need it if
|
||||||
|
you modified \`acconfig.h' or \`${configure_ac}'. You might want
|
||||||
|
to install the \`Autoconf' and \`GNU m4' packages. Grab them
|
||||||
|
from any GNU archive site."
|
||||||
|
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
|
||||||
|
test -z "$files" && files="config.h"
|
||||||
|
touch_files=
|
||||||
|
for f in $files; do
|
||||||
|
case "$f" in
|
||||||
|
*:*) touch_files="$touch_files "`echo "$f" |
|
||||||
|
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
|
||||||
|
*) touch_files="$touch_files $f.in";;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
touch $touch_files
|
||||||
|
;;
|
||||||
|
|
||||||
|
automake*)
|
||||||
|
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
|
||||||
|
# We have it, but it failed.
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo 1>&2 "\
|
||||||
|
WARNING: \`$1' is missing on your system. You should only need it if
|
||||||
|
you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
|
||||||
|
You might want to install the \`Automake' and \`Perl' packages.
|
||||||
|
Grab them from any GNU archive site."
|
||||||
|
find . -type f -name Makefile.am -print |
|
||||||
|
sed 's/\.am$/.in/' |
|
||||||
|
while read f; do touch "$f"; done
|
||||||
|
;;
|
||||||
|
|
||||||
|
autom4te)
|
||||||
|
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
|
||||||
|
# We have it, but it failed.
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo 1>&2 "\
|
||||||
|
WARNING: \`$1' is needed, and you do not seem to have it handy on your
|
||||||
|
system. You might have modified some files without having the
|
||||||
|
proper tools for further handling them.
|
||||||
|
You can get \`$1Help2man' as part of \`Autoconf' from any GNU
|
||||||
|
archive site."
|
||||||
|
|
||||||
|
file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
|
||||||
|
test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
|
||||||
|
if test -f "$file"; then
|
||||||
|
touch $file
|
||||||
|
else
|
||||||
|
test -z "$file" || exec >$file
|
||||||
|
echo "#! /bin/sh"
|
||||||
|
echo "# Created by GNU Automake missing as a replacement of"
|
||||||
|
echo "# $ $@"
|
||||||
|
echo "exit 0"
|
||||||
|
chmod +x $file
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
bison|yacc)
|
||||||
|
echo 1>&2 "\
|
||||||
|
WARNING: \`$1' is missing on your system. You should only need it if
|
||||||
|
you modified a \`.y' file. You may need the \`Bison' package
|
||||||
|
in order for those modifications to take effect. You can get
|
||||||
|
\`Bison' from any GNU archive site."
|
||||||
|
rm -f y.tab.c y.tab.h
|
||||||
|
if [ $# -ne 1 ]; then
|
||||||
|
eval LASTARG="\${$#}"
|
||||||
|
case "$LASTARG" in
|
||||||
|
*.y)
|
||||||
|
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
|
||||||
|
if [ -f "$SRCFILE" ]; then
|
||||||
|
cp "$SRCFILE" y.tab.c
|
||||||
|
fi
|
||||||
|
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
|
||||||
|
if [ -f "$SRCFILE" ]; then
|
||||||
|
cp "$SRCFILE" y.tab.h
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
if [ ! -f y.tab.h ]; then
|
||||||
|
echo >y.tab.h
|
||||||
|
fi
|
||||||
|
if [ ! -f y.tab.c ]; then
|
||||||
|
echo 'main() { return 0; }' >y.tab.c
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
lex|flex)
|
||||||
|
echo 1>&2 "\
|
||||||
|
WARNING: \`$1' is missing on your system. You should only need it if
|
||||||
|
you modified a \`.l' file. You may need the \`Flex' package
|
||||||
|
in order for those modifications to take effect. You can get
|
||||||
|
\`Flex' from any GNU archive site."
|
||||||
|
rm -f lex.yy.c
|
||||||
|
if [ $# -ne 1 ]; then
|
||||||
|
eval LASTARG="\${$#}"
|
||||||
|
case "$LASTARG" in
|
||||||
|
*.l)
|
||||||
|
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
|
||||||
|
if [ -f "$SRCFILE" ]; then
|
||||||
|
cp "$SRCFILE" lex.yy.c
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
if [ ! -f lex.yy.c ]; then
|
||||||
|
echo 'main() { return 0; }' >lex.yy.c
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
help2man)
|
||||||
|
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
|
||||||
|
# We have it, but it failed.
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo 1>&2 "\
|
||||||
|
WARNING: \`$1' is missing on your system. You should only need it if
|
||||||
|
you modified a dependency of a manual page. You may need the
|
||||||
|
\`Help2man' package in order for those modifications to take
|
||||||
|
effect. You can get \`Help2man' from any GNU archive site."
|
||||||
|
|
||||||
|
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
|
||||||
|
if test -z "$file"; then
|
||||||
|
file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
|
||||||
|
fi
|
||||||
|
if [ -f "$file" ]; then
|
||||||
|
touch $file
|
||||||
|
else
|
||||||
|
test -z "$file" || exec >$file
|
||||||
|
echo ".ab help2man is required to generate this page"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
|
||||||
|
makeinfo)
|
||||||
|
if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then
|
||||||
|
# We have makeinfo, but it failed.
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo 1>&2 "\
|
||||||
|
WARNING: \`$1' is missing on your system. You should only need it if
|
||||||
|
you modified a \`.texi' or \`.texinfo' file, or any other file
|
||||||
|
indirectly affecting the aspect of the manual. The spurious
|
||||||
|
call might also be the consequence of using a buggy \`make' (AIX,
|
||||||
|
DU, IRIX). You might want to install the \`Texinfo' package or
|
||||||
|
the \`GNU make' package. Grab either from any GNU archive site."
|
||||||
|
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
|
||||||
|
if test -z "$file"; then
|
||||||
|
file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
|
||||||
|
file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
|
||||||
|
fi
|
||||||
|
touch $file
|
||||||
|
;;
|
||||||
|
|
||||||
|
tar)
|
||||||
|
shift
|
||||||
|
if test -n "$run"; then
|
||||||
|
echo 1>&2 "ERROR: \`tar' requires --run"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# We have already tried tar in the generic part.
|
||||||
|
# Look for gnutar/gtar before invocation to avoid ugly error
|
||||||
|
# messages.
|
||||||
|
if (gnutar --version > /dev/null 2>&1); then
|
||||||
|
gnutar ${1+"$@"} && exit 0
|
||||||
|
fi
|
||||||
|
if (gtar --version > /dev/null 2>&1); then
|
||||||
|
gtar ${1+"$@"} && exit 0
|
||||||
|
fi
|
||||||
|
firstarg="$1"
|
||||||
|
if shift; then
|
||||||
|
case "$firstarg" in
|
||||||
|
*o*)
|
||||||
|
firstarg=`echo "$firstarg" | sed s/o//`
|
||||||
|
tar "$firstarg" ${1+"$@"} && exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
case "$firstarg" in
|
||||||
|
*h*)
|
||||||
|
firstarg=`echo "$firstarg" | sed s/h//`
|
||||||
|
tar "$firstarg" ${1+"$@"} && exit 0
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo 1>&2 "\
|
||||||
|
WARNING: I can't seem to be able to run \`tar' with the given arguments.
|
||||||
|
You may want to install GNU tar or Free paxutils, or check the
|
||||||
|
command line arguments."
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo 1>&2 "\
|
||||||
|
WARNING: \`$1' is needed, and you do not seem to have it handy on your
|
||||||
|
system. You might have modified some files without having the
|
||||||
|
proper tools for further handling them. Check the \`README' file,
|
||||||
|
it often tells you about the needed prerequirements for installing
|
||||||
|
this package. You may also peek at any GNU archive site, in case
|
||||||
|
some other package would contain this missing \`$1' program."
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
exit 0
|
101
mkinstalldirs
Normal file
101
mkinstalldirs
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
#! /bin/sh
|
||||||
|
# mkinstalldirs --- make directory hierarchy
|
||||||
|
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
|
||||||
|
# Created: 1993-05-16
|
||||||
|
# Public domain
|
||||||
|
|
||||||
|
# $Id: mkinstalldirs,v 1.13 1999/01/05 03:18:55 bje Exp $
|
||||||
|
|
||||||
|
errstatus=0
|
||||||
|
dirmode=""
|
||||||
|
|
||||||
|
usage="\
|
||||||
|
Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..."
|
||||||
|
|
||||||
|
# process command line arguments
|
||||||
|
while test $# -gt 0 ; do
|
||||||
|
case "${1}" in
|
||||||
|
-h | --help | --h* ) # -h for help
|
||||||
|
echo "${usage}" 1>&2; exit 0 ;;
|
||||||
|
-m ) # -m PERM arg
|
||||||
|
shift
|
||||||
|
test $# -eq 0 && { echo "${usage}" 1>&2; exit 1; }
|
||||||
|
dirmode="${1}"
|
||||||
|
shift ;;
|
||||||
|
-- ) shift; break ;; # stop option processing
|
||||||
|
-* ) echo "${usage}" 1>&2; exit 1 ;; # unknown option
|
||||||
|
* ) break ;; # first non-opt arg
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
for file
|
||||||
|
do
|
||||||
|
if test -d "$file"; then
|
||||||
|
shift
|
||||||
|
else
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
case $# in
|
||||||
|
0) exit 0 ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
case $dirmode in
|
||||||
|
'')
|
||||||
|
if mkdir -p -- . 2>/dev/null; then
|
||||||
|
echo "mkdir -p -- $*"
|
||||||
|
exec mkdir -p -- "$@"
|
||||||
|
fi ;;
|
||||||
|
*)
|
||||||
|
if mkdir -m "$dirmode" -p -- . 2>/dev/null; then
|
||||||
|
echo "mkdir -m $dirmode -p -- $*"
|
||||||
|
exec mkdir -m "$dirmode" -p -- "$@"
|
||||||
|
fi ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
for file
|
||||||
|
do
|
||||||
|
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
|
||||||
|
shift
|
||||||
|
|
||||||
|
pathcomp=
|
||||||
|
for d
|
||||||
|
do
|
||||||
|
pathcomp="$pathcomp$d"
|
||||||
|
case "$pathcomp" in
|
||||||
|
-* ) pathcomp=./$pathcomp ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if test ! -d "$pathcomp"; then
|
||||||
|
echo "mkdir $pathcomp"
|
||||||
|
|
||||||
|
mkdir "$pathcomp" || lasterr=$?
|
||||||
|
|
||||||
|
if test ! -d "$pathcomp"; then
|
||||||
|
errstatus=$lasterr
|
||||||
|
else
|
||||||
|
if test ! -z "$dirmode"; then
|
||||||
|
echo "chmod $dirmode $pathcomp"
|
||||||
|
|
||||||
|
lasterr=""
|
||||||
|
chmod "$dirmode" "$pathcomp" || lasterr=$?
|
||||||
|
|
||||||
|
if test ! -z "$lasterr"; then
|
||||||
|
errstatus=$lasterr
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
pathcomp="$pathcomp/"
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
|
exit $errstatus
|
||||||
|
|
||||||
|
# Local Variables:
|
||||||
|
# mode: shell-script
|
||||||
|
# sh-indentation: 3
|
||||||
|
# End:
|
||||||
|
# mkinstalldirs ends here
|
@ -1,149 +0,0 @@
|
|||||||
!define VER_MAYOR 0
|
|
||||||
!define VER_MINOR 72
|
|
||||||
!define APP_NAME "DOSBox ${VER_MAYOR}.${VER_MINOR} Installer"
|
|
||||||
!define COMP_NAME "DOSBox Team"
|
|
||||||
!define COPYRIGHT "Copyright © 2002-2008 DOSBox Team"
|
|
||||||
!define DESCRIPTION "DOSBox Installer"
|
|
||||||
|
|
||||||
VIProductVersion "${VER_MAYOR}.${VER_MINOR}.0.0"
|
|
||||||
VIAddVersionKey "ProductName" "${APP_NAME}"
|
|
||||||
VIAddVersionKey "CompanyName" "${COMP_NAME}"
|
|
||||||
VIAddVersionKey "FileDescription" "${DESCRIPTION}"
|
|
||||||
VIAddVersionKey "FileVersion" "${VER_MAYOR}.${VER_MINOR}.0.0"
|
|
||||||
VIAddVersionKey "ProductVersion" "${VER_MAYOR}, ${VER_MINOR}, 0, 0"
|
|
||||||
VIAddVersionKey "LegalCopyright" "${COPYRIGHT}"
|
|
||||||
|
|
||||||
; The name of the installer
|
|
||||||
Name "${APP_NAME}"
|
|
||||||
|
|
||||||
; The file to write
|
|
||||||
OutFile "DOSBox${VER_MAYOR}.${VER_MINOR}-win32-installer.exe"
|
|
||||||
|
|
||||||
; The default installation directory
|
|
||||||
InstallDir "$PROGRAMFILES\DOSBox-${VER_MAYOR}.${VER_MINOR}"
|
|
||||||
|
|
||||||
; The text to prompt the user to enter a directory
|
|
||||||
DirText "This will install DOSBox v${VER_MAYOR}.${VER_MINOR} on your computer. Choose a directory"
|
|
||||||
SetCompressor /solid lzma
|
|
||||||
|
|
||||||
|
|
||||||
LicenseData COPYING
|
|
||||||
LicenseText "DOSBox v${VER_MAYOR}.${VER_MINOR} License" "Next >"
|
|
||||||
|
|
||||||
; Else vista enables compatibility mode
|
|
||||||
RequestExecutionLevel admin
|
|
||||||
|
|
||||||
ComponentText "Select components for DOSBox"
|
|
||||||
; The stuff to install
|
|
||||||
Section "!Core files" Core
|
|
||||||
; Set output path to the installation directory.
|
|
||||||
ClearErrors
|
|
||||||
SetOutPath $INSTDIR
|
|
||||||
IfErrors error_createdir
|
|
||||||
SectionIn RO
|
|
||||||
|
|
||||||
; Put file there
|
|
||||||
|
|
||||||
CreateDirectory "$INSTDIR\capture"
|
|
||||||
CreateDirectory "$INSTDIR\zmbv"
|
|
||||||
File /oname=README.txt README
|
|
||||||
File /oname=COPYING.txt COPYING
|
|
||||||
File /oname=THANKS.txt THANKS
|
|
||||||
File /oname=NEWS.txt NEWS
|
|
||||||
File /oname=AUTHORS.txt AUTHORS
|
|
||||||
File /oname=INSTALL.txt INSTALL
|
|
||||||
File DOSBox.exe
|
|
||||||
File dosbox.conf
|
|
||||||
File SDL.dll
|
|
||||||
File SDL_net.dll
|
|
||||||
File /oname=zmbv\zmbv.dll zmbv.dll
|
|
||||||
File /oname=zmbv\zmbv.inf zmbv.inf
|
|
||||||
File /oname=zmbv\README.txt README.video
|
|
||||||
|
|
||||||
CreateDirectory "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}"
|
|
||||||
CreateDirectory "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video"
|
|
||||||
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0
|
|
||||||
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox.lnk" "$INSTDIR\DOSBox.exe" "-conf $\"$INSTDIR\dosbox.conf$\"" "$INSTDIR\DOSBox.exe" 0
|
|
||||||
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox (noconsole).lnk" "$INSTDIR\DOSBox.exe" "-noconsole -conf $\"$INSTDIR\dosbox.conf$\"" "$INSTDIR\DOSBox.exe" 0
|
|
||||||
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\README.lnk" "$INSTDIR\README.txt"
|
|
||||||
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox.conf.lnk" "notepad.exe" "$INSTDIR\dosbox.conf"
|
|
||||||
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Capture folder.lnk" "$INSTDIR\capture"
|
|
||||||
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video\Video instructions.lnk" "$INSTDIR\zmbv\README.txt"
|
|
||||||
;change outpath so the working directory gets set to zmbv
|
|
||||||
SetOutPath "$INSTDIR\zmbv"
|
|
||||||
; Shortcut creation depends on wether we are 9x of NT
|
|
||||||
ClearErrors
|
|
||||||
ReadRegStr $R0 HKLM "SOFTWARE\Microsoft\Windows NT\CurrentVersion" CurrentVersion
|
|
||||||
IfErrors we_9x we_nt
|
|
||||||
we_nt:
|
|
||||||
;shortcut for win NT
|
|
||||||
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video\Install movie codec.lnk" "rundll32" "setupapi,InstallHinfSection DefaultInstall 128 $INSTDIR\zmbv\zmbv.inf"
|
|
||||||
goto end
|
|
||||||
we_9x:
|
|
||||||
;shortcut for we_9x
|
|
||||||
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video\Install movie codec.lnk" "rundll" "setupx.dll,InstallHinfSection DefaultInstall 128 $INSTDIR\zmbv\zmbv.inf"
|
|
||||||
end:
|
|
||||||
SetOutPath $INSTDIR
|
|
||||||
WriteUninstaller "uninstall.exe"
|
|
||||||
|
|
||||||
goto end_section
|
|
||||||
|
|
||||||
error_createdir:
|
|
||||||
MessageBox MB_OK "Can't create DOSBox program directory, aborting."
|
|
||||||
Abort
|
|
||||||
goto end_section
|
|
||||||
|
|
||||||
end_section:
|
|
||||||
SectionEnd ; end the section
|
|
||||||
|
|
||||||
Section "Desktop Shortcut" SecDesktop
|
|
||||||
|
|
||||||
CreateShortCut "$DESKTOP\DOSBox ${VER_MAYOR}.${VER_MINOR}.lnk" "$INSTDIR\DOSBox.exe" "-conf $\"$INSTDIR\dosbox.conf$\"" "$INSTDIR\DOSBox.exe" 0
|
|
||||||
|
|
||||||
SectionEnd ; end the section
|
|
||||||
|
|
||||||
|
|
||||||
UninstallText "This will uninstall DOSBox v${VER_MAYOR}.${VER_MINOR}. Hit next to continue."
|
|
||||||
|
|
||||||
Section "Uninstall"
|
|
||||||
Delete "$DESKTOP\DOSBox ${VER_MAYOR}.${VER_MINOR}.lnk"
|
|
||||||
; remove registry keys
|
|
||||||
; remove files
|
|
||||||
Delete $INSTDIR\README.txt
|
|
||||||
Delete $INSTDIR\COPYING.txt
|
|
||||||
Delete $INSTDIR\THANKS.txt
|
|
||||||
Delete $INSTDIR\NEWS.txt
|
|
||||||
Delete $INSTDIR\AUTHORS.txt
|
|
||||||
Delete $INSTDIR\INSTALL.txt
|
|
||||||
Delete $INSTDIR\DOSBox.exe
|
|
||||||
Delete $INSTDIR\dosbox.conf
|
|
||||||
Delete $INSTDIR\SDL.dll
|
|
||||||
Delete $INSTDIR\SDL_net.dll
|
|
||||||
Delete $INSTDIR\zmbv\zmbv.dll
|
|
||||||
Delete $INSTDIR\zmbv\zmbv.inf
|
|
||||||
Delete $INSTDIR\zmbv\README.txt
|
|
||||||
;Files left by sdl taking over the console
|
|
||||||
Delete $INSTDIR\stdout.txt
|
|
||||||
Delete $INSTDIR\stderr.txt
|
|
||||||
|
|
||||||
; MUST REMOVE UNINSTALLER, too
|
|
||||||
Delete $INSTDIR\uninstall.exe
|
|
||||||
|
|
||||||
; remove shortcuts, if any.
|
|
||||||
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Uninstall.lnk"
|
|
||||||
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\README.lnk"
|
|
||||||
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox.lnk"
|
|
||||||
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox (noconsole).lnk"
|
|
||||||
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox.conf.lnk"
|
|
||||||
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Capture folder.lnk"
|
|
||||||
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video\Install movie codec.lnk"
|
|
||||||
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video\Video instructions.lnk"
|
|
||||||
; remove directories used.
|
|
||||||
RMDir "$INSTDIR\zmbv"
|
|
||||||
RMDir "$INSTDIR\capture"
|
|
||||||
RMDir "$INSTDIR"
|
|
||||||
RMDir "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video"
|
|
||||||
RMDir "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}"
|
|
||||||
SectionEnd
|
|
||||||
|
|
||||||
; eof
|
|
@ -1,32 +0,0 @@
|
|||||||
#!/usr/bin/perl
|
|
||||||
use integer;
|
|
||||||
open (THEFILE,'>','../src/hardware/ega-switch.h')
|
|
||||||
or die "Can't open my file $!";
|
|
||||||
|
|
||||||
print THEFILE "switch (bit_mask) {\n";
|
|
||||||
for ($i = 0; $i < 256; $i++) {
|
|
||||||
print THEFILE "\tcase $i:\n";
|
|
||||||
$b=128;
|
|
||||||
$add=0;
|
|
||||||
do {
|
|
||||||
if ($i & $b) {
|
|
||||||
print THEFILE "\t{\n";
|
|
||||||
print THEFILE "\t\tBit8u color=0;\n";
|
|
||||||
print THEFILE "\t\tif (pixels.b[0] & $b) color|=1;\n";
|
|
||||||
print THEFILE "\t\tif (pixels.b[1] & $b) color|=2;\n";
|
|
||||||
print THEFILE "\t\tif (pixels.b[2] & $b) color|=4;\n";
|
|
||||||
print THEFILE "\t\tif (pixels.b[3] & $b) color|=8;\n";
|
|
||||||
print THEFILE "\t\t*(write_pixels+$add)=color;\n";
|
|
||||||
print THEFILE "\t\t*(write_pixels+$add+512*1024)=color;\n";
|
|
||||||
print THEFILE "\t}\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
$b=$b >> 1;
|
|
||||||
$add=$add+1;
|
|
||||||
} until ($b == 0);
|
|
||||||
print THEFILE "\tbreak;\n";
|
|
||||||
}
|
|
||||||
print THEFILE "}\n";
|
|
||||||
|
|
||||||
|
|
||||||
close (THEFILE);
|
|
@ -1,25 +0,0 @@
|
|||||||
#!/usr/bin/perl
|
|
||||||
use integer;
|
|
||||||
open (THEFILE,'>','../src/hardware/font-switch.h')
|
|
||||||
or die "Can't open my file $!";
|
|
||||||
|
|
||||||
print THEFILE "switch (bit_mask) {\n";
|
|
||||||
for ($i = 0; $i < 256; $i++) {
|
|
||||||
print THEFILE "\tcase $i:\n";
|
|
||||||
$b=128;
|
|
||||||
$add=0;
|
|
||||||
do {
|
|
||||||
if ($i & $b) {
|
|
||||||
print THEFILE "\t\t*(draw+$add)=fg;\n";
|
|
||||||
} else {
|
|
||||||
print THEFILE "\t\t*(draw+$add)=bg;\n";
|
|
||||||
}
|
|
||||||
$b=$b >> 1;
|
|
||||||
$add=$add+1;
|
|
||||||
} until ($b == 0);
|
|
||||||
print THEFILE "\tbreak;\n";
|
|
||||||
}
|
|
||||||
print THEFILE "}\n";
|
|
||||||
|
|
||||||
|
|
||||||
close (THEFILE);
|
|
26
settings.h
Normal file
26
settings.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/* Enable the debugger */
|
||||||
|
//#define C_DEBUG
|
||||||
|
|
||||||
|
/* Enable logging of debug information */
|
||||||
|
//#define C_LOGGING
|
||||||
|
|
||||||
|
/* Use multi threading to speed up things on multi cpu's, also gives a nice frame-skipping effect :) */
|
||||||
|
#define C_THREADED
|
||||||
|
|
||||||
|
/* Enable debugging for several modules, requires C_LOGGING */
|
||||||
|
#define DEBUG_SBLASTER /* SoundBlaster Debugging*/
|
||||||
|
#define DEBUG_DMA /* DMA Debugging */
|
||||||
|
#define DEBUG_DOS /* DOS Debugging */
|
||||||
|
|
||||||
|
|
||||||
|
#define LOG_MSG S_Warn
|
||||||
|
|
||||||
|
#ifdef C_LOGGING
|
||||||
|
#define LOG_DEBUG S_Warn
|
||||||
|
#define LOG_WARN S_Warn
|
||||||
|
#define LOG_ERROR S_Warn
|
||||||
|
#else
|
||||||
|
#define LOG_DEBUG
|
||||||
|
#define LOG_WARN
|
||||||
|
#define LOG_ERROR
|
||||||
|
#endif
|
@ -1,20 +1,10 @@
|
|||||||
AM_CPPFLAGS = -I$(top_srcdir)/include
|
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||||
|
|
||||||
SUBDIRS = cpu debug dos fpu gui hardware libs ints misc shell platform
|
SUBDIRS = cpu debug dos fpu gui hardware ints misc shell platform
|
||||||
|
|
||||||
bin_PROGRAMS = dosbox
|
bin_PROGRAMS = dosbox
|
||||||
|
|
||||||
if HAVE_WINDRES
|
dosbox_SOURCES = dosbox.cpp
|
||||||
ico_stuff = winres.rc
|
|
||||||
endif
|
|
||||||
|
|
||||||
.rc.o:
|
|
||||||
$(WINDRES) -o $@ $<
|
|
||||||
|
|
||||||
dosbox_SOURCES = dosbox.cpp $(ico_stuff)
|
|
||||||
dosbox_LDADD = cpu/libcpu.a debug/libdebug.a dos/libdos.a fpu/libfpu.a hardware/libhardware.a gui/libgui.a \
|
dosbox_LDADD = cpu/libcpu.a debug/libdebug.a dos/libdos.a fpu/libfpu.a hardware/libhardware.a gui/libgui.a \
|
||||||
ints/libints.a misc/libmisc.a shell/libshell.a hardware/serialport/libserial.a libs/gui_tk/libgui_tk.a
|
ints/libints.a misc/libmisc.a shell/libshell.a -lcurses
|
||||||
|
EXTRA_DIST = dosbox.lang
|
||||||
EXTRA_DIST = winres.rc dosbox.ico
|
|
||||||
|
|
||||||
|
|
420
src/Makefile.in
Normal file
420
src/Makefile.in
Normal file
@ -0,0 +1,420 @@
|
|||||||
|
# Makefile.in generated by automake 1.6.1 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@
|
||||||
|
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_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@
|
||||||
|
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@
|
||||||
|
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||||
|
|
||||||
|
SUBDIRS = cpu debug dos fpu gui hardware ints misc shell platform
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
EXTRA_DIST = dosbox.lang
|
||||||
|
subdir = src
|
||||||
|
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||||
|
CONFIG_HEADER = $(top_builddir)/config.h
|
||||||
|
CONFIG_CLEAN_FILES =
|
||||||
|
bin_PROGRAMS = dosbox$(EXEEXT)
|
||||||
|
PROGRAMS = $(bin_PROGRAMS)
|
||||||
|
|
||||||
|
am_dosbox_OBJECTS = dosbox.$(OBJEXT)
|
||||||
|
dosbox_OBJECTS = $(am_dosbox_OBJECTS)
|
||||||
|
dosbox_DEPENDENCIES = 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
|
||||||
|
dosbox_LDFLAGS =
|
||||||
|
|
||||||
|
DEFS = @DEFS@
|
||||||
|
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
|
||||||
|
CPPFLAGS = @CPPFLAGS@
|
||||||
|
LDFLAGS = @LDFLAGS@
|
||||||
|
LIBS = @LIBS@
|
||||||
|
depcomp = $(SHELL) $(top_srcdir)/depcomp
|
||||||
|
am__depfiles_maybe = depfiles
|
||||||
|
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/dosbox.Po
|
||||||
|
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||||
|
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
|
||||||
|
CXXLD = $(CXX)
|
||||||
|
CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
|
||||||
|
-o $@
|
||||||
|
CXXFLAGS = @CXXFLAGS@
|
||||||
|
DIST_SOURCES = $(dosbox_SOURCES)
|
||||||
|
|
||||||
|
RECURSIVE_TARGETS = info-recursive dvi-recursive install-info-recursive \
|
||||||
|
uninstall-info-recursive all-recursive install-data-recursive \
|
||||||
|
install-exec-recursive installdirs-recursive install-recursive \
|
||||||
|
uninstall-recursive check-recursive installcheck-recursive
|
||||||
|
DIST_COMMON = Makefile.am Makefile.in
|
||||||
|
DIST_SUBDIRS = $(SUBDIRS)
|
||||||
|
SOURCES = $(dosbox_SOURCES)
|
||||||
|
|
||||||
|
all: all-recursive
|
||||||
|
|
||||||
|
.SUFFIXES:
|
||||||
|
.SUFFIXES: .cpp .o .obj
|
||||||
|
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
|
||||||
|
cd $(top_srcdir) && \
|
||||||
|
$(AUTOMAKE) --gnits src/Makefile
|
||||||
|
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||||
|
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
|
||||||
|
binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
|
||||||
|
install-binPROGRAMS: $(bin_PROGRAMS)
|
||||||
|
@$(NORMAL_INSTALL)
|
||||||
|
$(mkinstalldirs) $(DESTDIR)$(bindir)
|
||||||
|
@list='$(bin_PROGRAMS)'; for p in $$list; do \
|
||||||
|
p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
|
||||||
|
if test -f $$p \
|
||||||
|
; then \
|
||||||
|
p1=`echo "$$p1" | sed -e 's,^.*/,,'`; \
|
||||||
|
f=`echo $$p1|sed '$(transform);s/$$/$(EXEEXT)/'`; \
|
||||||
|
echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f"; \
|
||||||
|
$(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) $$p $(DESTDIR)$(bindir)/$$f; \
|
||||||
|
else :; fi; \
|
||||||
|
done
|
||||||
|
|
||||||
|
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,^.*/,,'`; \
|
||||||
|
echo " rm -f $(DESTDIR)$(bindir)/$$f"; \
|
||||||
|
rm -f $(DESTDIR)$(bindir)/$$f; \
|
||||||
|
done
|
||||||
|
|
||||||
|
clean-binPROGRAMS:
|
||||||
|
-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
|
||||||
|
dosbox$(EXEEXT): $(dosbox_OBJECTS) $(dosbox_DEPENDENCIES)
|
||||||
|
@rm -f dosbox$(EXEEXT)
|
||||||
|
$(CXXLINK) $(dosbox_LDFLAGS) $(dosbox_OBJECTS) $(dosbox_LDADD) $(LIBS)
|
||||||
|
|
||||||
|
mostlyclean-compile:
|
||||||
|
-rm -f *.$(OBJEXT) core *.core
|
||||||
|
|
||||||
|
distclean-compile:
|
||||||
|
-rm -f *.tab.c
|
||||||
|
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dosbox.Po@am__quote@
|
||||||
|
|
||||||
|
distclean-depend:
|
||||||
|
-rm -rf ./$(DEPDIR)
|
||||||
|
|
||||||
|
.cpp.o:
|
||||||
|
@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||||
|
@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
|
||||||
|
@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||||
|
$(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
|
||||||
|
|
||||||
|
.cpp.obj:
|
||||||
|
@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||||
|
@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
|
||||||
|
@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||||
|
$(CXXCOMPILE) -c -o $@ `cygpath -w $<`
|
||||||
|
CXXDEPMODE = @CXXDEPMODE@
|
||||||
|
uninstall-info-am:
|
||||||
|
|
||||||
|
# This directory's subdirectories are mostly independent; you can cd
|
||||||
|
# into them and run `make' without going through this Makefile.
|
||||||
|
# To change the values of `make' variables: instead of editing Makefiles,
|
||||||
|
# (1) if the variable is set in `config.status', edit `config.status'
|
||||||
|
# (which will cause the Makefiles to be regenerated when you run `make');
|
||||||
|
# (2) otherwise, pass the desired values on the `make' command line.
|
||||||
|
$(RECURSIVE_TARGETS):
|
||||||
|
@set fnord $$MAKEFLAGS; amf=$$2; \
|
||||||
|
dot_seen=no; \
|
||||||
|
target=`echo $@ | sed s/-recursive//`; \
|
||||||
|
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||||
|
echo "Making $$target in $$subdir"; \
|
||||||
|
if test "$$subdir" = "."; then \
|
||||||
|
dot_seen=yes; \
|
||||||
|
local_target="$$target-am"; \
|
||||||
|
else \
|
||||||
|
local_target="$$target"; \
|
||||||
|
fi; \
|
||||||
|
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|
||||||
|
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
|
||||||
|
done; \
|
||||||
|
if test "$$dot_seen" = "no"; then \
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
|
||||||
|
fi; test -z "$$fail"
|
||||||
|
|
||||||
|
mostlyclean-recursive clean-recursive distclean-recursive \
|
||||||
|
maintainer-clean-recursive:
|
||||||
|
@set fnord $$MAKEFLAGS; amf=$$2; \
|
||||||
|
dot_seen=no; \
|
||||||
|
case "$@" in \
|
||||||
|
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
|
||||||
|
*) list='$(SUBDIRS)' ;; \
|
||||||
|
esac; \
|
||||||
|
rev=''; for subdir in $$list; do \
|
||||||
|
if test "$$subdir" = "."; then :; else \
|
||||||
|
rev="$$subdir $$rev"; \
|
||||||
|
fi; \
|
||||||
|
done; \
|
||||||
|
rev="$$rev ."; \
|
||||||
|
target=`echo $@ | sed s/-recursive//`; \
|
||||||
|
for subdir in $$rev; do \
|
||||||
|
echo "Making $$target in $$subdir"; \
|
||||||
|
if test "$$subdir" = "."; then \
|
||||||
|
local_target="$$target-am"; \
|
||||||
|
else \
|
||||||
|
local_target="$$target"; \
|
||||||
|
fi; \
|
||||||
|
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|
||||||
|
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
|
||||||
|
done && test -z "$$fail"
|
||||||
|
tags-recursive:
|
||||||
|
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||||
|
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
|
||||||
|
done
|
||||||
|
|
||||||
|
ETAGS = etags
|
||||||
|
ETAGSFLAGS =
|
||||||
|
|
||||||
|
tags: TAGS
|
||||||
|
|
||||||
|
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||||
|
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||||
|
unique=`for i in $$list; do \
|
||||||
|
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||||
|
done | \
|
||||||
|
$(AWK) ' { files[$$0] = 1; } \
|
||||||
|
END { for (i in files) print i; }'`; \
|
||||||
|
mkid -fID $$unique
|
||||||
|
|
||||||
|
TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||||
|
$(TAGS_FILES) $(LISP)
|
||||||
|
tags=; \
|
||||||
|
here=`pwd`; \
|
||||||
|
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||||
|
if test "$$subdir" = .; then :; else \
|
||||||
|
test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
|
||||||
|
fi; \
|
||||||
|
done; \
|
||||||
|
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||||
|
unique=`for i in $$list; do \
|
||||||
|
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||||
|
done | \
|
||||||
|
$(AWK) ' { files[$$0] = 1; } \
|
||||||
|
END { for (i in files) print i; }'`; \
|
||||||
|
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|
||||||
|
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||||
|
$$tags $$unique
|
||||||
|
|
||||||
|
GTAGS:
|
||||||
|
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||||
|
&& cd $(top_srcdir) \
|
||||||
|
&& gtags -i $(GTAGS_ARGS) $$here
|
||||||
|
|
||||||
|
distclean-tags:
|
||||||
|
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH
|
||||||
|
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||||
|
|
||||||
|
top_distdir = ..
|
||||||
|
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
|
||||||
|
|
||||||
|
distdir: $(DISTFILES)
|
||||||
|
@for file in $(DISTFILES); 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
|
||||||
|
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||||
|
if test "$$subdir" = .; then :; else \
|
||||||
|
test -d $(distdir)/$$subdir \
|
||||||
|
|| mkdir $(distdir)/$$subdir \
|
||||||
|
|| exit 1; \
|
||||||
|
(cd $$subdir && \
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) \
|
||||||
|
top_distdir="$(top_distdir)" \
|
||||||
|
distdir=../$(distdir)/$$subdir \
|
||||||
|
distdir) \
|
||||||
|
|| exit 1; \
|
||||||
|
fi; \
|
||||||
|
done
|
||||||
|
check-am: all-am
|
||||||
|
check: check-recursive
|
||||||
|
all-am: Makefile $(PROGRAMS)
|
||||||
|
installdirs: installdirs-recursive
|
||||||
|
installdirs-am:
|
||||||
|
$(mkinstalldirs) $(DESTDIR)$(bindir)
|
||||||
|
|
||||||
|
install: install-recursive
|
||||||
|
install-exec: install-exec-recursive
|
||||||
|
install-data: install-data-recursive
|
||||||
|
uninstall: uninstall-recursive
|
||||||
|
|
||||||
|
install-am: all-am
|
||||||
|
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||||
|
|
||||||
|
installcheck: installcheck-recursive
|
||||||
|
install-strip:
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||||
|
INSTALL_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) stamp-h stamp-h[0-9]*
|
||||||
|
|
||||||
|
maintainer-clean-generic:
|
||||||
|
@echo "This command is intended for maintainers to use"
|
||||||
|
@echo "it deletes files that may require special tools to rebuild."
|
||||||
|
clean: clean-recursive
|
||||||
|
|
||||||
|
clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
|
||||||
|
|
||||||
|
distclean: distclean-recursive
|
||||||
|
|
||||||
|
distclean-am: clean-am distclean-compile distclean-depend \
|
||||||
|
distclean-generic distclean-tags
|
||||||
|
|
||||||
|
dvi: dvi-recursive
|
||||||
|
|
||||||
|
dvi-am:
|
||||||
|
|
||||||
|
info: info-recursive
|
||||||
|
|
||||||
|
info-am:
|
||||||
|
|
||||||
|
install-data-am:
|
||||||
|
|
||||||
|
install-exec-am: install-binPROGRAMS
|
||||||
|
|
||||||
|
install-info: install-info-recursive
|
||||||
|
|
||||||
|
install-man:
|
||||||
|
|
||||||
|
installcheck-am:
|
||||||
|
|
||||||
|
maintainer-clean: maintainer-clean-recursive
|
||||||
|
|
||||||
|
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||||
|
|
||||||
|
mostlyclean: mostlyclean-recursive
|
||||||
|
|
||||||
|
mostlyclean-am: mostlyclean-compile mostlyclean-generic
|
||||||
|
|
||||||
|
uninstall-am: uninstall-binPROGRAMS uninstall-info-am
|
||||||
|
|
||||||
|
uninstall-info: uninstall-info-recursive
|
||||||
|
|
||||||
|
.PHONY: $(RECURSIVE_TARGETS) GTAGS all all-am check check-am clean \
|
||||||
|
clean-binPROGRAMS clean-generic clean-recursive distclean \
|
||||||
|
distclean-compile distclean-depend distclean-generic \
|
||||||
|
distclean-recursive distclean-tags distdir dvi dvi-am \
|
||||||
|
dvi-recursive info info-am info-recursive install install-am \
|
||||||
|
install-binPROGRAMS install-data install-data-am \
|
||||||
|
install-data-recursive install-exec install-exec-am \
|
||||||
|
install-exec-recursive install-info install-info-am \
|
||||||
|
install-info-recursive install-man install-recursive \
|
||||||
|
install-strip installcheck installcheck-am installdirs \
|
||||||
|
installdirs-am installdirs-recursive maintainer-clean \
|
||||||
|
maintainer-clean-generic maintainer-clean-recursive mostlyclean \
|
||||||
|
mostlyclean-compile mostlyclean-generic mostlyclean-recursive \
|
||||||
|
tags tags-recursive uninstall uninstall-am \
|
||||||
|
uninstall-binPROGRAMS uninstall-info-am \
|
||||||
|
uninstall-info-recursive uninstall-recursive
|
||||||
|
|
||||||
|
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||||
|
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||||
|
.NOEXPORT:
|
@ -1,7 +1,5 @@
|
|||||||
SUBDIRS = core_full core_normal core_dyn_x86 core_dynrec
|
SUBDIRS = core_16
|
||||||
AM_CPPFLAGS = -I$(top_srcdir)/include
|
AM_CPPFLAGS = -I$(top_srcdir)/include
|
||||||
|
|
||||||
noinst_LIBRARIES = libcpu.a
|
noinst_LIBRARIES = libcpu.a
|
||||||
libcpu_a_SOURCES = callback.cpp cpu.cpp flags.cpp modrm.cpp modrm.h core_full.cpp instructions.h \
|
libcpu_a_SOURCES = callback.cpp cpu.cpp flags.cpp modrm.cpp modrm.h slow_16.cpp
|
||||||
paging.cpp lazyflags.h core_normal.cpp core_simple.cpp core_prefetch.cpp \
|
|
||||||
core_dyn_x86.cpp core_dynrec.cpp
|
|
401
src/cpu/Makefile.in
Normal file
401
src/cpu/Makefile.in
Normal file
@ -0,0 +1,401 @@
|
|||||||
|
# Makefile.in generated by automake 1.6.1 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@
|
||||||
|
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_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@
|
||||||
|
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@
|
||||||
|
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
|
||||||
|
subdir = src/cpu
|
||||||
|
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||||
|
CONFIG_HEADER = $(top_builddir)/config.h
|
||||||
|
CONFIG_CLEAN_FILES =
|
||||||
|
LIBRARIES = $(noinst_LIBRARIES)
|
||||||
|
|
||||||
|
libcpu_a_AR = $(AR) cru
|
||||||
|
libcpu_a_LIBADD =
|
||||||
|
am_libcpu_a_OBJECTS = callback.$(OBJEXT) cpu.$(OBJEXT) flags.$(OBJEXT) \
|
||||||
|
modrm.$(OBJEXT) slow_16.$(OBJEXT)
|
||||||
|
libcpu_a_OBJECTS = $(am_libcpu_a_OBJECTS)
|
||||||
|
|
||||||
|
DEFS = @DEFS@
|
||||||
|
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
|
||||||
|
CPPFLAGS = @CPPFLAGS@
|
||||||
|
LDFLAGS = @LDFLAGS@
|
||||||
|
LIBS = @LIBS@
|
||||||
|
depcomp = $(SHELL) $(top_srcdir)/depcomp
|
||||||
|
am__depfiles_maybe = depfiles
|
||||||
|
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/callback.Po ./$(DEPDIR)/cpu.Po \
|
||||||
|
@AMDEP_TRUE@ ./$(DEPDIR)/flags.Po ./$(DEPDIR)/modrm.Po \
|
||||||
|
@AMDEP_TRUE@ ./$(DEPDIR)/slow_16.Po
|
||||||
|
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||||
|
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
|
||||||
|
CXXLD = $(CXX)
|
||||||
|
CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
|
||||||
|
-o $@
|
||||||
|
CXXFLAGS = @CXXFLAGS@
|
||||||
|
CFLAGS = @CFLAGS@
|
||||||
|
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||||
|
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||||
|
CCLD = $(CC)
|
||||||
|
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
|
||||||
|
DIST_SOURCES = $(libcpu_a_SOURCES)
|
||||||
|
|
||||||
|
RECURSIVE_TARGETS = info-recursive dvi-recursive install-info-recursive \
|
||||||
|
uninstall-info-recursive all-recursive install-data-recursive \
|
||||||
|
install-exec-recursive installdirs-recursive install-recursive \
|
||||||
|
uninstall-recursive check-recursive installcheck-recursive
|
||||||
|
DIST_COMMON = Makefile.am Makefile.in
|
||||||
|
DIST_SUBDIRS = $(SUBDIRS)
|
||||||
|
SOURCES = $(libcpu_a_SOURCES)
|
||||||
|
|
||||||
|
all: all-recursive
|
||||||
|
|
||||||
|
.SUFFIXES:
|
||||||
|
.SUFFIXES: .cpp .o .obj
|
||||||
|
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
|
||||||
|
cd $(top_srcdir) && \
|
||||||
|
$(AUTOMAKE) --gnits src/cpu/Makefile
|
||||||
|
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||||
|
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
|
||||||
|
|
||||||
|
AR = ar
|
||||||
|
|
||||||
|
clean-noinstLIBRARIES:
|
||||||
|
-test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
|
||||||
|
libcpu.a: $(libcpu_a_OBJECTS) $(libcpu_a_DEPENDENCIES)
|
||||||
|
-rm -f libcpu.a
|
||||||
|
$(libcpu_a_AR) libcpu.a $(libcpu_a_OBJECTS) $(libcpu_a_LIBADD)
|
||||||
|
$(RANLIB) libcpu.a
|
||||||
|
|
||||||
|
mostlyclean-compile:
|
||||||
|
-rm -f *.$(OBJEXT) core *.core
|
||||||
|
|
||||||
|
distclean-compile:
|
||||||
|
-rm -f *.tab.c
|
||||||
|
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/callback.Po@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cpu.Po@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flags.Po@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/modrm.Po@am__quote@
|
||||||
|
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/slow_16.Po@am__quote@
|
||||||
|
|
||||||
|
distclean-depend:
|
||||||
|
-rm -rf ./$(DEPDIR)
|
||||||
|
|
||||||
|
.cpp.o:
|
||||||
|
@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||||
|
@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
|
||||||
|
@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||||
|
$(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
|
||||||
|
|
||||||
|
.cpp.obj:
|
||||||
|
@AMDEP_TRUE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||||
|
@AMDEP_TRUE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
|
||||||
|
@AMDEP_TRUE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||||
|
$(CXXCOMPILE) -c -o $@ `cygpath -w $<`
|
||||||
|
CXXDEPMODE = @CXXDEPMODE@
|
||||||
|
uninstall-info-am:
|
||||||
|
|
||||||
|
# This directory's subdirectories are mostly independent; you can cd
|
||||||
|
# into them and run `make' without going through this Makefile.
|
||||||
|
# To change the values of `make' variables: instead of editing Makefiles,
|
||||||
|
# (1) if the variable is set in `config.status', edit `config.status'
|
||||||
|
# (which will cause the Makefiles to be regenerated when you run `make');
|
||||||
|
# (2) otherwise, pass the desired values on the `make' command line.
|
||||||
|
$(RECURSIVE_TARGETS):
|
||||||
|
@set fnord $$MAKEFLAGS; amf=$$2; \
|
||||||
|
dot_seen=no; \
|
||||||
|
target=`echo $@ | sed s/-recursive//`; \
|
||||||
|
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||||
|
echo "Making $$target in $$subdir"; \
|
||||||
|
if test "$$subdir" = "."; then \
|
||||||
|
dot_seen=yes; \
|
||||||
|
local_target="$$target-am"; \
|
||||||
|
else \
|
||||||
|
local_target="$$target"; \
|
||||||
|
fi; \
|
||||||
|
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|
||||||
|
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
|
||||||
|
done; \
|
||||||
|
if test "$$dot_seen" = "no"; then \
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
|
||||||
|
fi; test -z "$$fail"
|
||||||
|
|
||||||
|
mostlyclean-recursive clean-recursive distclean-recursive \
|
||||||
|
maintainer-clean-recursive:
|
||||||
|
@set fnord $$MAKEFLAGS; amf=$$2; \
|
||||||
|
dot_seen=no; \
|
||||||
|
case "$@" in \
|
||||||
|
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
|
||||||
|
*) list='$(SUBDIRS)' ;; \
|
||||||
|
esac; \
|
||||||
|
rev=''; for subdir in $$list; do \
|
||||||
|
if test "$$subdir" = "."; then :; else \
|
||||||
|
rev="$$subdir $$rev"; \
|
||||||
|
fi; \
|
||||||
|
done; \
|
||||||
|
rev="$$rev ."; \
|
||||||
|
target=`echo $@ | sed s/-recursive//`; \
|
||||||
|
for subdir in $$rev; do \
|
||||||
|
echo "Making $$target in $$subdir"; \
|
||||||
|
if test "$$subdir" = "."; then \
|
||||||
|
local_target="$$target-am"; \
|
||||||
|
else \
|
||||||
|
local_target="$$target"; \
|
||||||
|
fi; \
|
||||||
|
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|
||||||
|
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
|
||||||
|
done && test -z "$$fail"
|
||||||
|
tags-recursive:
|
||||||
|
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||||
|
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
|
||||||
|
done
|
||||||
|
|
||||||
|
ETAGS = etags
|
||||||
|
ETAGSFLAGS =
|
||||||
|
|
||||||
|
tags: TAGS
|
||||||
|
|
||||||
|
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||||
|
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||||
|
unique=`for i in $$list; do \
|
||||||
|
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||||
|
done | \
|
||||||
|
$(AWK) ' { files[$$0] = 1; } \
|
||||||
|
END { for (i in files) print i; }'`; \
|
||||||
|
mkid -fID $$unique
|
||||||
|
|
||||||
|
TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||||
|
$(TAGS_FILES) $(LISP)
|
||||||
|
tags=; \
|
||||||
|
here=`pwd`; \
|
||||||
|
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||||
|
if test "$$subdir" = .; then :; else \
|
||||||
|
test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
|
||||||
|
fi; \
|
||||||
|
done; \
|
||||||
|
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||||
|
unique=`for i in $$list; do \
|
||||||
|
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||||
|
done | \
|
||||||
|
$(AWK) ' { files[$$0] = 1; } \
|
||||||
|
END { for (i in files) print i; }'`; \
|
||||||
|
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|
||||||
|
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||||
|
$$tags $$unique
|
||||||
|
|
||||||
|
GTAGS:
|
||||||
|
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||||
|
&& cd $(top_srcdir) \
|
||||||
|
&& gtags -i $(GTAGS_ARGS) $$here
|
||||||
|
|
||||||
|
distclean-tags:
|
||||||
|
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH
|
||||||
|
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||||
|
|
||||||
|
top_distdir = ../..
|
||||||
|
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
|
||||||
|
|
||||||
|
distdir: $(DISTFILES)
|
||||||
|
@for file in $(DISTFILES); 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
|
||||||
|
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||||
|
if test "$$subdir" = .; then :; else \
|
||||||
|
test -d $(distdir)/$$subdir \
|
||||||
|
|| mkdir $(distdir)/$$subdir \
|
||||||
|
|| exit 1; \
|
||||||
|
(cd $$subdir && \
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) \
|
||||||
|
top_distdir="$(top_distdir)" \
|
||||||
|
distdir=../$(distdir)/$$subdir \
|
||||||
|
distdir) \
|
||||||
|
|| exit 1; \
|
||||||
|
fi; \
|
||||||
|
done
|
||||||
|
check-am: all-am
|
||||||
|
check: check-recursive
|
||||||
|
all-am: Makefile $(LIBRARIES)
|
||||||
|
installdirs: installdirs-recursive
|
||||||
|
installdirs-am:
|
||||||
|
|
||||||
|
install: install-recursive
|
||||||
|
install-exec: install-exec-recursive
|
||||||
|
install-data: install-data-recursive
|
||||||
|
uninstall: uninstall-recursive
|
||||||
|
|
||||||
|
install-am: all-am
|
||||||
|
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||||
|
|
||||||
|
installcheck: installcheck-recursive
|
||||||
|
install-strip:
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||||
|
INSTALL_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) stamp-h stamp-h[0-9]*
|
||||||
|
|
||||||
|
maintainer-clean-generic:
|
||||||
|
@echo "This command is intended for maintainers to use"
|
||||||
|
@echo "it deletes files that may require special tools to rebuild."
|
||||||
|
clean: clean-recursive
|
||||||
|
|
||||||
|
clean-am: clean-generic clean-noinstLIBRARIES mostlyclean-am
|
||||||
|
|
||||||
|
distclean: distclean-recursive
|
||||||
|
|
||||||
|
distclean-am: clean-am distclean-compile distclean-depend \
|
||||||
|
distclean-generic distclean-tags
|
||||||
|
|
||||||
|
dvi: dvi-recursive
|
||||||
|
|
||||||
|
dvi-am:
|
||||||
|
|
||||||
|
info: info-recursive
|
||||||
|
|
||||||
|
info-am:
|
||||||
|
|
||||||
|
install-data-am:
|
||||||
|
|
||||||
|
install-exec-am:
|
||||||
|
|
||||||
|
install-info: install-info-recursive
|
||||||
|
|
||||||
|
install-man:
|
||||||
|
|
||||||
|
installcheck-am:
|
||||||
|
|
||||||
|
maintainer-clean: maintainer-clean-recursive
|
||||||
|
|
||||||
|
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||||
|
|
||||||
|
mostlyclean: mostlyclean-recursive
|
||||||
|
|
||||||
|
mostlyclean-am: mostlyclean-compile mostlyclean-generic
|
||||||
|
|
||||||
|
uninstall-am: uninstall-info-am
|
||||||
|
|
||||||
|
uninstall-info: uninstall-info-recursive
|
||||||
|
|
||||||
|
.PHONY: $(RECURSIVE_TARGETS) GTAGS all all-am check check-am clean \
|
||||||
|
clean-generic clean-noinstLIBRARIES clean-recursive distclean \
|
||||||
|
distclean-compile distclean-depend distclean-generic \
|
||||||
|
distclean-recursive distclean-tags distdir dvi dvi-am \
|
||||||
|
dvi-recursive info info-am info-recursive install install-am \
|
||||||
|
install-data install-data-am install-data-recursive \
|
||||||
|
install-exec install-exec-am install-exec-recursive \
|
||||||
|
install-info install-info-am install-info-recursive install-man \
|
||||||
|
install-recursive install-strip installcheck installcheck-am \
|
||||||
|
installdirs installdirs-am installdirs-recursive \
|
||||||
|
maintainer-clean maintainer-clean-generic \
|
||||||
|
maintainer-clean-recursive mostlyclean mostlyclean-compile \
|
||||||
|
mostlyclean-generic mostlyclean-recursive tags tags-recursive \
|
||||||
|
uninstall uninstall-am uninstall-info-am \
|
||||||
|
uninstall-info-recursive uninstall-recursive
|
||||||
|
|
||||||
|
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||||
|
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||||
|
.NOEXPORT:
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2009 The DOSBox Team
|
* Copyright (C) 2002 The DOSBox Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -9,41 +9,39 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Library General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: callback.cpp,v 1.40 2009/03/03 18:30:41 c2woody Exp $ */
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "dosbox.h"
|
#include "dosbox.h"
|
||||||
#include "callback.h"
|
#include "callback.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
|
|
||||||
/* CallBack are located at 0xF100:0 (see CB_SEG in callback.h)
|
|
||||||
|
/* CallBack are located at 0xC800:0
|
||||||
And they are 16 bytes each and you can define them to behave in certain ways like a
|
And they are 16 bytes each and you can define them to behave in certain ways like a
|
||||||
far return or and IRET
|
far return or and IRET
|
||||||
*/
|
*/
|
||||||
|
|
||||||
CallBack_Handler CallBack_Handlers[CB_MAX];
|
|
||||||
char* CallBack_Description[CB_MAX];
|
|
||||||
|
|
||||||
static Bitu call_stop,call_idle,call_default,call_default2;
|
CallBack_Handler CallBack_Handlers[CB_MAX];
|
||||||
Bitu call_priv_io;
|
static Bitu call_runint16,call_idle,call_default,call_runfar16;
|
||||||
|
|
||||||
static Bitu illegal_handler(void) {
|
static Bitu illegal_handler(void) {
|
||||||
E_Exit("Illegal CallBack Called");
|
E_Exit("Illegal CallBack Called");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* when this returns -1 all CallBacks are taken */
|
||||||
Bitu CALLBACK_Allocate(void) {
|
Bitu CALLBACK_Allocate(void) {
|
||||||
for (Bitu i=1;(i<CB_MAX);i++) {
|
for (Bitu i=0;(i<CB_MAX);i++) {
|
||||||
if (CallBack_Handlers[i]==&illegal_handler) {
|
if (CallBack_Handlers[i]==&illegal_handler) {
|
||||||
CallBack_Handlers[i]=0;
|
CallBack_Handlers[i]=0;
|
||||||
return i;
|
return i;
|
||||||
@ -53,523 +51,122 @@ Bitu CALLBACK_Allocate(void) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CALLBACK_DeAllocate(Bitu in) {
|
|
||||||
CallBack_Handlers[in]=&illegal_handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void CALLBACK_Idle(void) {
|
void CALLBACK_Idle(void) {
|
||||||
/* this makes the cpu execute instructions to handle irq's and then come back */
|
/* this makes the cpu execute instructions to handle irq's and then come back */
|
||||||
Bitu oldIF=GETFLAG(IF);
|
Bit16u oldcs=Segs[cs].value;
|
||||||
SETFLAGBIT(IF,true);
|
|
||||||
Bit16u oldcs=SegValue(cs);
|
|
||||||
Bit32u oldeip=reg_eip;
|
Bit32u oldeip=reg_eip;
|
||||||
SegSet16(cs,CB_SEG);
|
SetSegment_16(cs,CB_SEG);
|
||||||
reg_eip=call_idle*CB_SIZE;
|
reg_eip=call_idle<<4;
|
||||||
DOSBOX_RunMachine();
|
DOSBOX_RunMachine();
|
||||||
reg_eip=oldeip;
|
reg_eip=oldeip;
|
||||||
SegSet16(cs,oldcs);
|
SetSegment_16(cs,oldcs);
|
||||||
SETFLAGBIT(IF,oldIF);
|
|
||||||
if (!CPU_CycleAutoAdjust && CPU_Cycles>0)
|
|
||||||
CPU_Cycles=0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bitu default_handler(void) {
|
static Bitu default_handler(void) {
|
||||||
LOG(LOG_CPU,LOG_ERROR)("Illegal Unhandled Interrupt Called %X",lastint);
|
LOG_WARN("Illegal Unhandled Interrupt Called %d",lastint);
|
||||||
return CBRET_NONE;
|
return CBRET_NONE;
|
||||||
}
|
};
|
||||||
|
|
||||||
static Bitu stop_handler(void) {
|
static Bitu stop_handler(void) {
|
||||||
return CBRET_STOP;
|
return CBRET_STOP;
|
||||||
}
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void CALLBACK_RunRealFar(Bit16u seg,Bit16u off) {
|
void CALLBACK_RunRealFar(Bit16u seg,Bit16u off) {
|
||||||
reg_sp-=4;
|
real_writew((Bit16u)CB_SEG,(call_runfar16<<4)+1,off);
|
||||||
mem_writew(SegPhys(ss)+reg_sp,call_stop*CB_SIZE);
|
real_writew((Bit16u)CB_SEG,(call_runfar16<<4)+3,seg);
|
||||||
mem_writew(SegPhys(ss)+reg_sp+2,CB_SEG);
|
|
||||||
Bit32u oldeip=reg_eip;
|
Bit32u oldeip=reg_eip;
|
||||||
Bit16u oldcs=SegValue(cs);
|
Bit16u oldcs=Segs[cs].value;
|
||||||
reg_eip=off;
|
reg_eip=call_runfar16<<4;
|
||||||
SegSet16(cs,seg);
|
SetSegment_16(cs,CB_SEG);
|
||||||
DOSBOX_RunMachine();
|
DOSBOX_RunMachine();
|
||||||
reg_eip=oldeip;
|
reg_eip=oldeip;
|
||||||
SegSet16(cs,oldcs);
|
SetSegment_16(cs,oldcs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CALLBACK_RunRealInt(Bit8u intnum) {
|
void CALLBACK_RunRealInt(Bit8u intnum) {
|
||||||
|
real_writeb((Bit16u)CB_SEG,(call_runint16<<4)+1,intnum);
|
||||||
Bit32u oldeip=reg_eip;
|
Bit32u oldeip=reg_eip;
|
||||||
Bit16u oldcs=SegValue(cs);
|
Bit16u oldcs=Segs[cs].value;
|
||||||
reg_eip=(CB_MAX*CB_SIZE)+(intnum*6);
|
reg_eip=call_runint16<<4;
|
||||||
SegSet16(cs,CB_SEG);
|
SetSegment_16(cs,CB_SEG);
|
||||||
DOSBOX_RunMachine();
|
DOSBOX_RunMachine();
|
||||||
reg_eip=oldeip;
|
reg_eip=oldeip;
|
||||||
SegSet16(cs,oldcs);
|
SetSegment_16(cs,oldcs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void CALLBACK_SZF(bool val) {
|
void CALLBACK_SZF(bool val) {
|
||||||
Bit16u tempf=mem_readw(SegPhys(ss)+reg_sp+4) & 0xFFBF;
|
Bit16u tempf=real_readw(Segs[ss].value,reg_sp+4) & 0xFFBF;
|
||||||
Bit16u newZF=(val==true) << 6;
|
Bit16u newZF=(val==true) << 6;
|
||||||
mem_writew(SegPhys(ss)+reg_sp+4,(tempf | newZF));
|
real_writew(Segs[ss].value,reg_sp+4,(tempf | newZF));
|
||||||
}
|
};
|
||||||
|
|
||||||
void CALLBACK_SCF(bool val) {
|
void CALLBACK_SCF(bool val) {
|
||||||
Bit16u tempf=mem_readw(SegPhys(ss)+reg_sp+4) & 0xFFFE;
|
Bit16u tempf=real_readw(Segs[ss].value,reg_sp+4) & 0xFFFE;
|
||||||
Bit16u newCF=(val==true);
|
Bit16u newCF=(val==true);
|
||||||
mem_writew(SegPhys(ss)+reg_sp+4,(tempf | newCF));
|
real_writew(Segs[ss].value,reg_sp+4,(tempf | newCF));
|
||||||
}
|
};
|
||||||
|
|
||||||
void CALLBACK_SetDescription(Bitu nr, const char* descr) {
|
|
||||||
if (descr) {
|
|
||||||
CallBack_Description[nr] = new char[strlen(descr)+1];
|
|
||||||
strcpy(CallBack_Description[nr],descr);
|
|
||||||
} else
|
|
||||||
CallBack_Description[nr] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* CALLBACK_GetDescription(Bitu nr) {
|
|
||||||
if (nr>=CB_MAX) return 0;
|
|
||||||
return CallBack_Description[nr];
|
|
||||||
}
|
|
||||||
|
|
||||||
Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_cb=true) {
|
bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type) {
|
||||||
if (callback>=CB_MAX)
|
if (callback>=CB_MAX) return false;
|
||||||
return 0;
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case CB_RETN:
|
|
||||||
if (use_cb) {
|
|
||||||
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
|
|
||||||
phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction
|
|
||||||
phys_writew(physAddress+0x02, callback); //The immediate word
|
|
||||||
physAddress+=4;
|
|
||||||
}
|
|
||||||
phys_writeb(physAddress+0x00,(Bit8u)0xC3); //A RETN Instruction
|
|
||||||
return (use_cb?5:1);
|
|
||||||
case CB_RETF:
|
case CB_RETF:
|
||||||
if (use_cb) {
|
real_writeb((Bit16u)CB_SEG,(callback<<4),(Bit8u)0xFE); //GRP 4
|
||||||
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
|
real_writeb((Bit16u)CB_SEG,(callback<<4)+1,(Bit8u)0x38); //Extra Callback instruction
|
||||||
phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction
|
real_writew((Bit16u)CB_SEG,(callback<<4)+2,callback); //The immediate word
|
||||||
phys_writew(physAddress+0x02, callback); //The immediate word
|
real_writeb((Bit16u)CB_SEG,(callback<<4)+4,(Bit8u)0xCB); //A RETF Instruction
|
||||||
physAddress+=4;
|
break;
|
||||||
}
|
|
||||||
phys_writeb(physAddress+0x00,(Bit8u)0xCB); //A RETF Instruction
|
|
||||||
return (use_cb?5:1);
|
|
||||||
case CB_RETF8:
|
|
||||||
if (use_cb) {
|
|
||||||
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
|
|
||||||
phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction
|
|
||||||
phys_writew(physAddress+0x02, callback); //The immediate word
|
|
||||||
physAddress+=4;
|
|
||||||
}
|
|
||||||
phys_writeb(physAddress+0x00,(Bit8u)0xCA); //A RETF 8 Instruction
|
|
||||||
phys_writew(physAddress+0x01,(Bit16u)0x0008);
|
|
||||||
return (use_cb?7:3);
|
|
||||||
case CB_IRET:
|
case CB_IRET:
|
||||||
if (use_cb) {
|
real_writeb((Bit16u)CB_SEG,(callback<<4),(Bit8u)0xFE); //GRP 4
|
||||||
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
|
real_writeb((Bit16u)CB_SEG,(callback<<4)+1,(Bit8u)0x38); //Extra Callback instruction
|
||||||
phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction
|
real_writew((Bit16u)CB_SEG,(callback<<4)+2,callback); //The immediate word
|
||||||
phys_writew(physAddress+0x02,callback); //The immediate word
|
real_writeb((Bit16u)CB_SEG,(callback<<4)+4,(Bit8u)0xCF); //An IRET Instruction
|
||||||
physAddress+=4;
|
break;
|
||||||
}
|
|
||||||
phys_writeb(physAddress+0x00,(Bit8u)0xCF); //An IRET Instruction
|
|
||||||
return (use_cb?5:1);
|
|
||||||
case CB_IRETD:
|
|
||||||
if (use_cb) {
|
|
||||||
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
|
|
||||||
phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction
|
|
||||||
phys_writew(physAddress+0x02,callback); //The immediate word
|
|
||||||
physAddress+=4;
|
|
||||||
}
|
|
||||||
phys_writeb(physAddress+0x00,(Bit8u)0x66); //An IRETD Instruction
|
|
||||||
phys_writeb(physAddress+0x01,(Bit8u)0xCF);
|
|
||||||
return (use_cb?6:2);
|
|
||||||
case CB_IRET_STI:
|
|
||||||
phys_writeb(physAddress+0x00,(Bit8u)0xFB); //STI
|
|
||||||
if (use_cb) {
|
|
||||||
phys_writeb(physAddress+0x01,(Bit8u)0xFE); //GRP 4
|
|
||||||
phys_writeb(physAddress+0x02,(Bit8u)0x38); //Extra Callback instruction
|
|
||||||
phys_writew(physAddress+0x03, callback); //The immediate word
|
|
||||||
physAddress+=4;
|
|
||||||
}
|
|
||||||
phys_writeb(physAddress+0x01,(Bit8u)0xCF); //An IRET Instruction
|
|
||||||
return (use_cb?6:2);
|
|
||||||
case CB_IRET_EOI_PIC1:
|
|
||||||
if (use_cb) {
|
|
||||||
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
|
|
||||||
phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction
|
|
||||||
phys_writew(physAddress+0x02,callback); //The immediate word
|
|
||||||
physAddress+=4;
|
|
||||||
}
|
|
||||||
phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax
|
|
||||||
phys_writeb(physAddress+0x01,(Bit8u)0xb0); // mov al, 0x20
|
|
||||||
phys_writeb(physAddress+0x02,(Bit8u)0x20);
|
|
||||||
phys_writeb(physAddress+0x03,(Bit8u)0xe6); // out 0x20, al
|
|
||||||
phys_writeb(physAddress+0x04,(Bit8u)0x20);
|
|
||||||
phys_writeb(physAddress+0x05,(Bit8u)0x58); // pop ax
|
|
||||||
phys_writeb(physAddress+0x06,(Bit8u)0xcf); //An IRET Instruction
|
|
||||||
return (use_cb?0x0b:0x07);
|
|
||||||
case CB_IRQ0: // timer int8
|
|
||||||
if (use_cb) {
|
|
||||||
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
|
|
||||||
phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction
|
|
||||||
phys_writew(physAddress+0x02,callback); //The immediate word
|
|
||||||
physAddress+=4;
|
|
||||||
}
|
|
||||||
phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax
|
|
||||||
phys_writeb(physAddress+0x01,(Bit8u)0x52); // push dx
|
|
||||||
phys_writeb(physAddress+0x02,(Bit8u)0x1e); // push ds
|
|
||||||
phys_writew(physAddress+0x03,(Bit16u)0x1ccd); // int 1c
|
|
||||||
phys_writeb(physAddress+0x05,(Bit8u)0xfa); // cli
|
|
||||||
phys_writeb(physAddress+0x06,(Bit8u)0x1f); // pop ds
|
|
||||||
phys_writeb(physAddress+0x07,(Bit8u)0x5a); // pop dx
|
|
||||||
phys_writew(physAddress+0x08,(Bit16u)0x20b0); // mov al, 0x20
|
|
||||||
phys_writew(physAddress+0x0a,(Bit16u)0x20e6); // out 0x20, al
|
|
||||||
phys_writeb(physAddress+0x0c,(Bit8u)0x58); // pop ax
|
|
||||||
phys_writeb(physAddress+0x0d,(Bit8u)0xcf); //An IRET Instruction
|
|
||||||
return (use_cb?0x12:0x0e);
|
|
||||||
case CB_IRQ1: // keyboard int9
|
|
||||||
phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax
|
|
||||||
phys_writew(physAddress+0x01,(Bit16u)0x60e4); // in al, 0x60
|
|
||||||
phys_writew(physAddress+0x03,(Bit16u)0x4fb4); // mov ah, 0x4f
|
|
||||||
phys_writeb(physAddress+0x05,(Bit8u)0xf9); // stc
|
|
||||||
phys_writew(physAddress+0x06,(Bit16u)0x15cd); // int 15
|
|
||||||
if (use_cb) {
|
|
||||||
phys_writew(physAddress+0x08,(Bit16u)0x0473); // jc skip
|
|
||||||
phys_writeb(physAddress+0x0a,(Bit8u)0xFE); //GRP 4
|
|
||||||
phys_writeb(physAddress+0x0b,(Bit8u)0x38); //Extra Callback instruction
|
|
||||||
phys_writew(physAddress+0x0c,callback); //The immediate word
|
|
||||||
// jump here to (skip):
|
|
||||||
physAddress+=6;
|
|
||||||
}
|
|
||||||
phys_writeb(physAddress+0x08,(Bit8u)0xfa); // cli
|
|
||||||
phys_writew(physAddress+0x09,(Bit16u)0x20b0); // mov al, 0x20
|
|
||||||
phys_writew(physAddress+0x0b,(Bit16u)0x20e6); // out 0x20, al
|
|
||||||
phys_writeb(physAddress+0x0d,(Bit8u)0x58); // pop ax
|
|
||||||
phys_writeb(physAddress+0x0e,(Bit8u)0xcf); //An IRET Instruction
|
|
||||||
return (use_cb?0x15:0x0f);
|
|
||||||
case CB_IRQ9: // pic cascade interrupt
|
|
||||||
if (use_cb) {
|
|
||||||
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
|
|
||||||
phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction
|
|
||||||
phys_writew(physAddress+0x02,callback); //The immediate word
|
|
||||||
physAddress+=4;
|
|
||||||
}
|
|
||||||
phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax
|
|
||||||
phys_writew(physAddress+0x01,(Bit16u)0x61b0); // mov al, 0x61
|
|
||||||
phys_writew(physAddress+0x03,(Bit16u)0xa0e6); // out 0xa0, al
|
|
||||||
phys_writew(physAddress+0x05,(Bit16u)0x0acd); // int a
|
|
||||||
phys_writeb(physAddress+0x07,(Bit8u)0xfa); // cli
|
|
||||||
phys_writeb(physAddress+0x08,(Bit8u)0x58); // pop ax
|
|
||||||
phys_writeb(physAddress+0x09,(Bit8u)0xcf); //An IRET Instruction
|
|
||||||
return (use_cb?0x0e:0x0a);
|
|
||||||
case CB_IRQ12: // ps2 mouse int74
|
|
||||||
if (!use_cb) E_Exit("int74 callback must implement a callback handler!");
|
|
||||||
phys_writeb(physAddress+0x00,(Bit8u)0x1e); // push ds
|
|
||||||
phys_writeb(physAddress+0x01,(Bit8u)0x06); // push es
|
|
||||||
phys_writew(physAddress+0x02,(Bit16u)0x6066); // pushad
|
|
||||||
phys_writeb(physAddress+0x04,(Bit8u)0xfc); // cld
|
|
||||||
phys_writeb(physAddress+0x05,(Bit8u)0xfb); // sti
|
|
||||||
phys_writeb(physAddress+0x06,(Bit8u)0xFE); //GRP 4
|
|
||||||
phys_writeb(physAddress+0x07,(Bit8u)0x38); //Extra Callback instruction
|
|
||||||
phys_writew(physAddress+0x08,callback); //The immediate word
|
|
||||||
return 0x0a;
|
|
||||||
case CB_IRQ12_RET: // ps2 mouse int74 return
|
|
||||||
if (use_cb) {
|
|
||||||
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
|
|
||||||
phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction
|
|
||||||
phys_writew(physAddress+0x02,callback); //The immediate word
|
|
||||||
physAddress+=4;
|
|
||||||
}
|
|
||||||
phys_writeb(physAddress+0x00,(Bit8u)0xfa); // cli
|
|
||||||
phys_writew(physAddress+0x01,(Bit16u)0x20b0); // mov al, 0x20
|
|
||||||
phys_writew(physAddress+0x03,(Bit16u)0xa0e6); // out 0xa0, al
|
|
||||||
phys_writew(physAddress+0x05,(Bit16u)0x20e6); // out 0x20, al
|
|
||||||
phys_writew(physAddress+0x07,(Bit16u)0x6166); // popad
|
|
||||||
phys_writeb(physAddress+0x09,(Bit8u)0x07); // pop es
|
|
||||||
phys_writeb(physAddress+0x0a,(Bit8u)0x1f); // pop ds
|
|
||||||
phys_writeb(physAddress+0x0b,(Bit8u)0xcf); //An IRET Instruction
|
|
||||||
return (use_cb?0x10:0x0c);
|
|
||||||
case CB_IRQ6_PCJR: // pcjr keyboard interrupt
|
|
||||||
phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax
|
|
||||||
phys_writew(physAddress+0x01,(Bit16u)0x60e4); // in al, 0x60
|
|
||||||
phys_writew(physAddress+0x03,(Bit16u)0xe03c); // cmp al, 0xe0
|
|
||||||
if (use_cb) {
|
|
||||||
phys_writew(physAddress+0x05,(Bit16u)0x0674); // je skip
|
|
||||||
phys_writeb(physAddress+0x07,(Bit8u)0xFE); //GRP 4
|
|
||||||
phys_writeb(physAddress+0x08,(Bit8u)0x38); //Extra Callback instruction
|
|
||||||
phys_writew(physAddress+0x09,callback); //The immediate word
|
|
||||||
physAddress+=4;
|
|
||||||
} else {
|
|
||||||
phys_writew(physAddress+0x05,(Bit16u)0x0274); // je skip
|
|
||||||
}
|
|
||||||
phys_writew(physAddress+0x07,(Bit16u)0x09cd); // int 9
|
|
||||||
// jump here to (skip):
|
|
||||||
phys_writeb(physAddress+0x09,(Bit8u)0xfa); // cli
|
|
||||||
phys_writew(physAddress+0x0a,(Bit16u)0x20b0); // mov al, 0x20
|
|
||||||
phys_writew(physAddress+0x0c,(Bit16u)0x20e6); // out 0x20, al
|
|
||||||
phys_writeb(physAddress+0x0e,(Bit8u)0x58); // pop ax
|
|
||||||
phys_writeb(physAddress+0x0f,(Bit8u)0xcf); //An IRET Instruction
|
|
||||||
return (use_cb?0x14:0x10);
|
|
||||||
case CB_MOUSE:
|
|
||||||
phys_writew(physAddress+0x00,(Bit16u)0x07eb); // jmp i33hd
|
|
||||||
physAddress+=9;
|
|
||||||
// jump here to (i33hd):
|
|
||||||
if (use_cb) {
|
|
||||||
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
|
|
||||||
phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction
|
|
||||||
phys_writew(physAddress+0x02,callback); //The immediate word
|
|
||||||
physAddress+=4;
|
|
||||||
}
|
|
||||||
phys_writeb(physAddress+0x00,(Bit8u)0xCF); //An IRET Instruction
|
|
||||||
return (use_cb?0x0e:0x0a);
|
|
||||||
case CB_INT16:
|
|
||||||
phys_writeb(physAddress+0x00,(Bit8u)0xFB); //STI
|
|
||||||
if (use_cb) {
|
|
||||||
phys_writeb(physAddress+0x01,(Bit8u)0xFE); //GRP 4
|
|
||||||
phys_writeb(physAddress+0x02,(Bit8u)0x38); //Extra Callback instruction
|
|
||||||
phys_writew(physAddress+0x03, callback); //The immediate word
|
|
||||||
physAddress+=4;
|
|
||||||
}
|
|
||||||
phys_writeb(physAddress+0x01,(Bit8u)0xCF); //An IRET Instruction
|
|
||||||
for (Bitu i=0;i<=0x0b;i++) phys_writeb(physAddress+0x02+i,0x90);
|
|
||||||
phys_writew(physAddress+0x0e,(Bit16u)0xedeb); //jmp callback
|
|
||||||
return (use_cb?0x10:0x0c);
|
|
||||||
case CB_INT29: // fast console output
|
|
||||||
if (use_cb) {
|
|
||||||
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
|
|
||||||
phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction
|
|
||||||
phys_writew(physAddress+0x02,callback); //The immediate word
|
|
||||||
physAddress+=4;
|
|
||||||
}
|
|
||||||
phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax
|
|
||||||
phys_writew(physAddress+0x01,(Bit16u)0x0eb4); // mov ah, 0x0e
|
|
||||||
phys_writew(physAddress+0x03,(Bit16u)0x10cd); // int 10
|
|
||||||
phys_writeb(physAddress+0x05,(Bit8u)0x58); // pop ax
|
|
||||||
phys_writeb(physAddress+0x06,(Bit8u)0xcf); //An IRET Instruction
|
|
||||||
return (use_cb?0x0b:0x07);
|
|
||||||
case CB_HOOKABLE:
|
|
||||||
phys_writeb(physAddress+0x00,(Bit8u)0xEB); //jump near
|
|
||||||
phys_writeb(physAddress+0x01,(Bit8u)0x03); //offset
|
|
||||||
phys_writeb(physAddress+0x02,(Bit8u)0x90); //NOP
|
|
||||||
phys_writeb(physAddress+0x03,(Bit8u)0x90); //NOP
|
|
||||||
phys_writeb(physAddress+0x04,(Bit8u)0x90); //NOP
|
|
||||||
if (use_cb) {
|
|
||||||
phys_writeb(physAddress+0x05,(Bit8u)0xFE); //GRP 4
|
|
||||||
phys_writeb(physAddress+0x06,(Bit8u)0x38); //Extra Callback instruction
|
|
||||||
phys_writew(physAddress+0x07,callback); //The immediate word
|
|
||||||
physAddress+=4;
|
|
||||||
}
|
|
||||||
phys_writeb(physAddress+0x05,(Bit8u)0xCB); //A RETF Instruction
|
|
||||||
return (use_cb?0x0a:0x06);
|
|
||||||
case CB_TDE_IRET: // TandyDAC end transfer
|
|
||||||
if (use_cb) {
|
|
||||||
phys_writeb(physAddress+0x00,(Bit8u)0xFE); //GRP 4
|
|
||||||
phys_writeb(physAddress+0x01,(Bit8u)0x38); //Extra Callback instruction
|
|
||||||
phys_writew(physAddress+0x02,callback); //The immediate word
|
|
||||||
physAddress+=4;
|
|
||||||
}
|
|
||||||
phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax
|
|
||||||
phys_writeb(physAddress+0x01,(Bit8u)0xb8); // mov ax, 0x91fb
|
|
||||||
phys_writew(physAddress+0x02,(Bit16u)0x91fb);
|
|
||||||
phys_writew(physAddress+0x04,(Bit16u)0x15cd); // int 15
|
|
||||||
phys_writeb(physAddress+0x06,(Bit8u)0xfa); // cli
|
|
||||||
phys_writew(physAddress+0x07,(Bit16u)0x20b0); // mov al, 0x20
|
|
||||||
phys_writew(physAddress+0x09,(Bit16u)0x20e6); // out 0x20, al
|
|
||||||
phys_writeb(physAddress+0x0b,(Bit8u)0x58); // pop ax
|
|
||||||
phys_writeb(physAddress+0x0c,(Bit8u)0xcf); //An IRET Instruction
|
|
||||||
return (use_cb?0x11:0x0d);
|
|
||||||
/* case CB_IPXESR: // IPX ESR
|
|
||||||
if (!use_cb) E_Exit("ipx esr must implement a callback handler!");
|
|
||||||
phys_writeb(physAddress+0x00,(Bit8u)0x1e); // push ds
|
|
||||||
phys_writeb(physAddress+0x01,(Bit8u)0x06); // push es
|
|
||||||
phys_writew(physAddress+0x02,(Bit16u)0xa00f); // push fs
|
|
||||||
phys_writew(physAddress+0x04,(Bit16u)0xa80f); // push gs
|
|
||||||
phys_writeb(physAddress+0x06,(Bit8u)0x60); // pusha
|
|
||||||
phys_writeb(physAddress+0x07,(Bit8u)0xFE); //GRP 4
|
|
||||||
phys_writeb(physAddress+0x08,(Bit8u)0x38); //Extra Callback instruction
|
|
||||||
phys_writew(physAddress+0x09,callback); //The immediate word
|
|
||||||
phys_writeb(physAddress+0x0b,(Bit8u)0xCB); //A RETF Instruction
|
|
||||||
return 0x0c;
|
|
||||||
case CB_IPXESR_RET: // IPX ESR return
|
|
||||||
if (use_cb) E_Exit("ipx esr return must not implement a callback handler!");
|
|
||||||
phys_writeb(physAddress+0x00,(Bit8u)0xfa); // cli
|
|
||||||
phys_writew(physAddress+0x01,(Bit16u)0x20b0); // mov al, 0x20
|
|
||||||
phys_writew(physAddress+0x03,(Bit16u)0xa0e6); // out 0xa0, al
|
|
||||||
phys_writew(physAddress+0x05,(Bit16u)0x20e6); // out 0x20, al
|
|
||||||
phys_writeb(physAddress+0x07,(Bit8u)0x61); // popa
|
|
||||||
phys_writew(physAddress+0x08,(Bit16u)0xA90F); // pop gs
|
|
||||||
phys_writew(physAddress+0x0a,(Bit16u)0xA10F); // pop fs
|
|
||||||
phys_writeb(physAddress+0x0c,(Bit8u)0x07); // pop es
|
|
||||||
phys_writeb(physAddress+0x0d,(Bit8u)0x1f); // pop ds
|
|
||||||
phys_writeb(physAddress+0x0e,(Bit8u)0xcf); //An IRET Instruction
|
|
||||||
return 0x0f; */
|
|
||||||
case CB_INT21:
|
|
||||||
phys_writeb(physAddress+0x00,(Bit8u)0xFB); //STI
|
|
||||||
if (use_cb) {
|
|
||||||
phys_writeb(physAddress+0x01,(Bit8u)0xFE); //GRP 4
|
|
||||||
phys_writeb(physAddress+0x02,(Bit8u)0x38); //Extra Callback instruction
|
|
||||||
phys_writew(physAddress+0x03, callback); //The immediate word
|
|
||||||
physAddress+=4;
|
|
||||||
}
|
|
||||||
phys_writeb(physAddress+0x01,(Bit8u)0xCF); //An IRET Instruction
|
|
||||||
phys_writeb(physAddress+0x02,(Bit8u)0xCB); //A RETF Instruction
|
|
||||||
return (use_cb?7:3);
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
E_Exit("CALLBACK:Setup:Illegal type %d",type);
|
E_Exit("CALLBACK:Setup:Illegal type %d",type);
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,const char* descr) {
|
}
|
||||||
if (callback>=CB_MAX) return false;
|
|
||||||
CALLBACK_SetupExtra(callback,type,CALLBACK_PhysPointer(callback)+0,(handler!=NULL));
|
|
||||||
CallBack_Handlers[callback]=handler;
|
CallBack_Handlers[callback]=handler;
|
||||||
CALLBACK_SetDescription(callback,descr);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bitu CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,PhysPt addr,const char* descr) {
|
void CALLBACK_Init(void) {
|
||||||
if (callback>=CB_MAX) return 0;
|
|
||||||
Bitu csize=CALLBACK_SetupExtra(callback,type,addr,(handler!=NULL));
|
|
||||||
if (csize>0) {
|
|
||||||
CallBack_Handlers[callback]=handler;
|
|
||||||
CALLBACK_SetDescription(callback,descr);
|
|
||||||
}
|
|
||||||
return csize;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CALLBACK_RemoveSetup(Bitu callback) {
|
|
||||||
for (Bitu i = 0;i < 16;i++) {
|
|
||||||
phys_writeb(CALLBACK_PhysPointer(callback)+i ,(Bit8u) 0x00);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CALLBACK_HandlerObject::~CALLBACK_HandlerObject(){
|
|
||||||
if(!installed) return;
|
|
||||||
if(m_type == CALLBACK_HandlerObject::SETUP) {
|
|
||||||
if(vectorhandler.installed){
|
|
||||||
//See if we are the current handler. if so restore the old one
|
|
||||||
if(RealGetVec(vectorhandler.interrupt) == Get_RealPointer()) {
|
|
||||||
RealSetVec(vectorhandler.interrupt,vectorhandler.old_vector);
|
|
||||||
} else
|
|
||||||
LOG(LOG_MISC,LOG_WARN)("Interrupt vector changed on %X %s",vectorhandler.interrupt,CALLBACK_GetDescription(m_callback));
|
|
||||||
}
|
|
||||||
CALLBACK_RemoveSetup(m_callback);
|
|
||||||
} else if(m_type == CALLBACK_HandlerObject::SETUPAT){
|
|
||||||
E_Exit("Callback:SETUP at not handled yet.");
|
|
||||||
} else if(m_type == CALLBACK_HandlerObject::NONE){
|
|
||||||
//Do nothing. Merely DeAllocate the callback
|
|
||||||
} else E_Exit("what kind of callback is this!");
|
|
||||||
if(CallBack_Description[m_callback]) delete [] CallBack_Description[m_callback];
|
|
||||||
CallBack_Description[m_callback] = 0;
|
|
||||||
CALLBACK_DeAllocate(m_callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CALLBACK_HandlerObject::Install(CallBack_Handler handler,Bitu type,const char* description){
|
|
||||||
if(!installed) {
|
|
||||||
installed=true;
|
|
||||||
m_type=SETUP;
|
|
||||||
m_callback=CALLBACK_Allocate();
|
|
||||||
CALLBACK_Setup(m_callback,handler,type,description);
|
|
||||||
} else E_Exit("Allready installed");
|
|
||||||
}
|
|
||||||
void CALLBACK_HandlerObject::Install(CallBack_Handler handler,Bitu type,PhysPt addr,const char* description){
|
|
||||||
if(!installed) {
|
|
||||||
installed=true;
|
|
||||||
m_type=SETUP;
|
|
||||||
m_callback=CALLBACK_Allocate();
|
|
||||||
CALLBACK_Setup(m_callback,handler,type,addr,description);
|
|
||||||
} else E_Exit("Allready installed");
|
|
||||||
}
|
|
||||||
|
|
||||||
void CALLBACK_HandlerObject::Allocate(CallBack_Handler handler,const char* description) {
|
|
||||||
if(!installed) {
|
|
||||||
installed=true;
|
|
||||||
m_type=NONE;
|
|
||||||
m_callback=CALLBACK_Allocate();
|
|
||||||
CALLBACK_SetDescription(m_callback,description);
|
|
||||||
CallBack_Handlers[m_callback]=handler;
|
|
||||||
} else E_Exit("Allready installed");
|
|
||||||
}
|
|
||||||
|
|
||||||
void CALLBACK_HandlerObject::Set_RealVec(Bit8u vec){
|
|
||||||
if(!vectorhandler.installed) {
|
|
||||||
vectorhandler.installed=true;
|
|
||||||
vectorhandler.interrupt=vec;
|
|
||||||
RealSetVec(vec,Get_RealPointer(),vectorhandler.old_vector);
|
|
||||||
} else E_Exit ("double usage of vector handler");
|
|
||||||
}
|
|
||||||
|
|
||||||
void CALLBACK_Init(Section* sec) {
|
|
||||||
Bitu i;
|
Bitu i;
|
||||||
for (i=0;i<CB_MAX;i++) {
|
for (i=0;i<CB_MAX;i++) {
|
||||||
CallBack_Handlers[i]=&illegal_handler;
|
CallBack_Handlers[i]=&illegal_handler;
|
||||||
}
|
}
|
||||||
|
/* Setup the Software interrupt handler */
|
||||||
/* Setup the Stop Handler */
|
call_runint16=CALLBACK_Allocate();
|
||||||
call_stop=CALLBACK_Allocate();
|
CallBack_Handlers[call_runint16]=stop_handler;
|
||||||
CallBack_Handlers[call_stop]=stop_handler;
|
real_writeb((Bit16u)CB_SEG,(call_runint16<<4),0xCD);
|
||||||
CALLBACK_SetDescription(call_stop,"stop");
|
real_writeb((Bit16u)CB_SEG,(call_runint16<<4)+2,0xFE);
|
||||||
phys_writeb(CALLBACK_PhysPointer(call_stop)+0,0xFE);
|
real_writeb((Bit16u)CB_SEG,(call_runint16<<4)+3,0x38);
|
||||||
phys_writeb(CALLBACK_PhysPointer(call_stop)+1,0x38);
|
real_writew((Bit16u)CB_SEG,(call_runint16<<4)+4,call_runint16);
|
||||||
phys_writew(CALLBACK_PhysPointer(call_stop)+2,call_stop);
|
/* Setup the Far Call handler */
|
||||||
|
call_runfar16=CALLBACK_Allocate();
|
||||||
|
CallBack_Handlers[call_runfar16]=stop_handler;
|
||||||
|
real_writeb((Bit16u)CB_SEG,(call_runfar16<<4),0x9A);
|
||||||
|
real_writeb((Bit16u)CB_SEG,(call_runfar16<<4)+5,0xFE);
|
||||||
|
real_writeb((Bit16u)CB_SEG,(call_runfar16<<4)+6,0x38);
|
||||||
|
real_writew((Bit16u)CB_SEG,(call_runfar16<<4)+7,call_runfar16);
|
||||||
/* Setup the idle handler */
|
/* Setup the idle handler */
|
||||||
call_idle=CALLBACK_Allocate();
|
call_idle=CALLBACK_Allocate();
|
||||||
CallBack_Handlers[call_idle]=stop_handler;
|
CallBack_Handlers[call_idle]=stop_handler;
|
||||||
CALLBACK_SetDescription(call_idle,"idle");
|
for (i=0;i<=11;i++) real_writeb((Bit16u)CB_SEG,(call_idle<<4)+i,0x90);
|
||||||
for (i=0;i<=11;i++) phys_writeb(CALLBACK_PhysPointer(call_idle)+i,0x90);
|
real_writeb((Bit16u)CB_SEG,(call_idle<<4)+12,0xFE);
|
||||||
phys_writeb(CALLBACK_PhysPointer(call_idle)+12,0xFE);
|
real_writeb((Bit16u)CB_SEG,(call_idle<<4)+13,0x38);
|
||||||
phys_writeb(CALLBACK_PhysPointer(call_idle)+13,0x38);
|
real_writew((Bit16u)CB_SEG,(call_idle<<4)+14,call_idle);
|
||||||
phys_writew(CALLBACK_PhysPointer(call_idle)+14,call_idle);
|
/* Setup all Interrupt to point to the default handler */
|
||||||
|
|
||||||
/* Default handlers for unhandled interrupts that have to be non-null */
|
|
||||||
call_default=CALLBACK_Allocate();
|
call_default=CALLBACK_Allocate();
|
||||||
CALLBACK_Setup(call_default,&default_handler,CB_IRET,"default");
|
CALLBACK_Setup(call_default,&default_handler,CB_IRET);
|
||||||
call_default2=CALLBACK_Allocate();
|
for (i=0;i<256;i++) {
|
||||||
CALLBACK_Setup(call_default2,&default_handler,CB_IRET,"default");
|
|
||||||
|
|
||||||
/* 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));
|
real_writed(0,i*4,CALLBACK_RealPointer(call_default));
|
||||||
}
|
}
|
||||||
/* Setup block of 0xCD 0xxx instructions */
|
|
||||||
PhysPt rint_base=(CB_SEG << 4)+CB_MAX*CB_SIZE;
|
|
||||||
for (i=0;i<=0xff;i++) {
|
|
||||||
phys_writeb(rint_base,0xCD);
|
|
||||||
phys_writeb(rint_base+1,i);
|
|
||||||
phys_writeb(rint_base+2,0xFE);
|
|
||||||
phys_writeb(rint_base+3,0x38);
|
|
||||||
phys_writew(rint_base+4,call_stop);
|
|
||||||
rint_base+=6;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
// setup a few interrupt handlers that point to bios IRETs by default
|
|
||||||
real_writed(0,0x0e*4,CALLBACK_RealPointer(call_default2)); //design your own railroad
|
|
||||||
real_writed(0,0x66*4,CALLBACK_RealPointer(call_default)); //war2d
|
|
||||||
real_writed(0,0x67*4,CALLBACK_RealPointer(call_default));
|
|
||||||
real_writed(0,0x68*4,CALLBACK_RealPointer(call_default));
|
|
||||||
real_writed(0,0x5c*4,CALLBACK_RealPointer(call_default)); //Network stuff
|
|
||||||
//real_writed(0,0xf*4,0); some games don't like it
|
|
||||||
|
|
||||||
call_priv_io=CALLBACK_Allocate();
|
|
||||||
|
|
||||||
// virtualizable in-out opcodes
|
|
||||||
phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x00,(Bit8u)0xec); // in al, dx
|
|
||||||
phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x01,(Bit8u)0xcb); // retf
|
|
||||||
phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x02,(Bit8u)0xed); // in ax, dx
|
|
||||||
phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x03,(Bit8u)0xcb); // retf
|
|
||||||
phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x04,(Bit8u)0x66); // in eax, dx
|
|
||||||
phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x05,(Bit8u)0xed);
|
|
||||||
phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x06,(Bit8u)0xcb); // retf
|
|
||||||
|
|
||||||
phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x08,(Bit8u)0xee); // out dx, al
|
|
||||||
phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x09,(Bit8u)0xcb); // retf
|
|
||||||
phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x0a,(Bit8u)0xef); // out dx, ax
|
|
||||||
phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x0b,(Bit8u)0xcb); // retf
|
|
||||||
phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x0c,(Bit8u)0x66); // out dx, eax
|
|
||||||
phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x0d,(Bit8u)0xef);
|
|
||||||
phys_writeb(CALLBACK_PhysPointer(call_priv_io)+0x0e,(Bit8u)0xcb); // retf
|
|
||||||
}
|
|
||||||
|
3
src/cpu/core_16/Makefile.am
Normal file
3
src/cpu/core_16/Makefile.am
Normal file
@ -0,0 +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 \
|
||||||
|
prefix_66_of.h
|
244
src/cpu/core_16/Makefile.in
Normal file
244
src/cpu/core_16/Makefile.in
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
# Makefile.in generated by automake 1.6.1 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@
|
||||||
|
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_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@
|
||||||
|
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@
|
||||||
|
|
||||||
|
noinst_HEADERS = helpers.h instructions.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
|
||||||
|
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||||
|
CONFIG_HEADER = $(top_builddir)/config.h
|
||||||
|
CONFIG_CLEAN_FILES =
|
||||||
|
DIST_SOURCES =
|
||||||
|
HEADERS = $(noinst_HEADERS)
|
||||||
|
|
||||||
|
DIST_COMMON = $(noinst_HEADERS) Makefile.am Makefile.in
|
||||||
|
all: all-am
|
||||||
|
|
||||||
|
.SUFFIXES:
|
||||||
|
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
|
||||||
|
cd $(top_srcdir) && \
|
||||||
|
$(AUTOMAKE) --gnits src/cpu/core_16/Makefile
|
||||||
|
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||||
|
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
|
||||||
|
uninstall-info-am:
|
||||||
|
|
||||||
|
ETAGS = etags
|
||||||
|
ETAGSFLAGS =
|
||||||
|
|
||||||
|
tags: TAGS
|
||||||
|
|
||||||
|
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||||
|
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||||
|
unique=`for i in $$list; do \
|
||||||
|
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||||
|
done | \
|
||||||
|
$(AWK) ' { files[$$0] = 1; } \
|
||||||
|
END { for (i in files) print i; }'`; \
|
||||||
|
mkid -fID $$unique
|
||||||
|
|
||||||
|
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
|
||||||
|
$(TAGS_FILES) $(LISP)
|
||||||
|
tags=; \
|
||||||
|
here=`pwd`; \
|
||||||
|
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||||
|
unique=`for i in $$list; do \
|
||||||
|
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||||
|
done | \
|
||||||
|
$(AWK) ' { files[$$0] = 1; } \
|
||||||
|
END { for (i in files) print i; }'`; \
|
||||||
|
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|
||||||
|
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||||
|
$$tags $$unique
|
||||||
|
|
||||||
|
GTAGS:
|
||||||
|
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||||
|
&& cd $(top_srcdir) \
|
||||||
|
&& gtags -i $(GTAGS_ARGS) $$here
|
||||||
|
|
||||||
|
distclean-tags:
|
||||||
|
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH
|
||||||
|
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||||
|
|
||||||
|
top_distdir = ../../..
|
||||||
|
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
|
||||||
|
|
||||||
|
distdir: $(DISTFILES)
|
||||||
|
@for file in $(DISTFILES); 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 $(HEADERS)
|
||||||
|
|
||||||
|
installdirs:
|
||||||
|
|
||||||
|
install: install-am
|
||||||
|
install-exec: install-exec-am
|
||||||
|
install-data: install-data-am
|
||||||
|
uninstall: uninstall-am
|
||||||
|
|
||||||
|
install-am: all-am
|
||||||
|
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||||
|
|
||||||
|
installcheck: installcheck-am
|
||||||
|
install-strip:
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||||
|
INSTALL_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) stamp-h stamp-h[0-9]*
|
||||||
|
|
||||||
|
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 distclean-tags
|
||||||
|
|
||||||
|
dvi: dvi-am
|
||||||
|
|
||||||
|
dvi-am:
|
||||||
|
|
||||||
|
info: info-am
|
||||||
|
|
||||||
|
info-am:
|
||||||
|
|
||||||
|
install-data-am:
|
||||||
|
|
||||||
|
install-exec-am:
|
||||||
|
|
||||||
|
install-info: install-info-am
|
||||||
|
|
||||||
|
install-man:
|
||||||
|
|
||||||
|
installcheck-am:
|
||||||
|
|
||||||
|
maintainer-clean: maintainer-clean-am
|
||||||
|
|
||||||
|
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||||
|
|
||||||
|
mostlyclean: mostlyclean-am
|
||||||
|
|
||||||
|
mostlyclean-am: mostlyclean-generic
|
||||||
|
|
||||||
|
uninstall-am: uninstall-info-am
|
||||||
|
|
||||||
|
.PHONY: GTAGS all all-am check check-am clean clean-generic distclean \
|
||||||
|
distclean-generic distclean-tags distdir dvi dvi-am info \
|
||||||
|
info-am install install-am install-data install-data-am \
|
||||||
|
install-exec install-exec-am install-info install-info-am \
|
||||||
|
install-man install-strip installcheck installcheck-am \
|
||||||
|
installdirs maintainer-clean maintainer-clean-generic \
|
||||||
|
mostlyclean mostlyclean-generic tags uninstall uninstall-am \
|
||||||
|
uninstall-info-am
|
||||||
|
|
||||||
|
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||||
|
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||||
|
.NOEXPORT:
|
76
src/cpu/core_16/helpers.h
Normal file
76
src/cpu/core_16/helpers.h
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2002 The DOSBox Team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#define GetEAa \
|
||||||
|
EAPoint eaa=(*lookupEATable)[rm]();
|
||||||
|
|
||||||
|
#define GetRMEAa \
|
||||||
|
GetRM; \
|
||||||
|
GetEAa;
|
||||||
|
|
||||||
|
#define RMEbGb(inst) \
|
||||||
|
{ \
|
||||||
|
GetRMrb; \
|
||||||
|
if (rm >= 0xc0 ) {GetEArb;inst(*earb,*rmrb,LoadRb,SaveRb);} \
|
||||||
|
else {GetEAa;inst(eaa,*rmrb,LoadMb,SaveMb);} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define RMGbEb(inst) \
|
||||||
|
{ \
|
||||||
|
GetRMrb; \
|
||||||
|
if (rm >= 0xc0 ) {GetEArb;inst(*rmrb,*earb,LoadRb,SaveRb);} \
|
||||||
|
else {GetEAa;inst(*rmrb,LoadMb(eaa),LoadRb,SaveRb);} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define RMEwGw(inst) \
|
||||||
|
{ \
|
||||||
|
GetRMrw; \
|
||||||
|
if (rm >= 0xc0 ) {GetEArw;inst(*earw,*rmrw,LoadRw,SaveRw);} \
|
||||||
|
else {GetEAa;inst(eaa,*rmrw,LoadMw,SaveMw);} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define RMGwEw(inst) \
|
||||||
|
{ \
|
||||||
|
GetRMrw; \
|
||||||
|
if (rm >= 0xc0 ) {GetEArw;inst(*rmrw,*earw,LoadRw,SaveRw);} \
|
||||||
|
else {GetEAa;inst(*rmrw,LoadMw(eaa),LoadRw,SaveRw);} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define RMEdGd(inst) \
|
||||||
|
{ \
|
||||||
|
GetRMrd; \
|
||||||
|
if (rm >= 0xc0 ) {GetEArd;inst(*eard,*rmrd,LoadRd,SaveRd);} \
|
||||||
|
else {GetEAa;inst(eaa,*rmrd,LoadMd,SaveMd);} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define RMGdEd(inst) \
|
||||||
|
{ \
|
||||||
|
GetRMrd; \
|
||||||
|
if (rm >= 0xc0 ) {GetEArd;inst(*rmrd,*eard,LoadRd,SaveRd);} \
|
||||||
|
else {GetEAa;inst(*rmrd,LoadMd(eaa),LoadRd,SaveRd);} \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ALIb(inst) \
|
||||||
|
{ inst(reg_al,Fetchb(),LoadRb,SaveRb)}
|
||||||
|
|
||||||
|
#define AXIw(inst) \
|
||||||
|
{ inst(reg_ax,Fetchw(),LoadRw,SaveRw);}
|
||||||
|
|
||||||
|
#define EAXId(inst) \
|
||||||
|
{ inst(reg_eax,Fetchd(),LoadRd,SaveRd);}
|
593
src/cpu/core_16/instructions.h
Normal file
593
src/cpu/core_16/instructions.h
Normal file
@ -0,0 +1,593 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Jumps */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Could perhaps do some things with 8 and 16 bit operations like shifts, doing them in 32 bit regs
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define JumpSIb(blah) \
|
||||||
|
if (blah) { \
|
||||||
|
ADDIPFAST(Fetchbs()); \
|
||||||
|
} else { \
|
||||||
|
ADDIPFAST(1); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define JumpSIw(blah) \
|
||||||
|
if (blah) { \
|
||||||
|
ADDIPFAST(Fetchws()); \
|
||||||
|
} else { \
|
||||||
|
ADDIPFAST(2); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define INTERRUPT(blah) \
|
||||||
|
{ \
|
||||||
|
Bit8u new_num=blah; \
|
||||||
|
SAVEIP; \
|
||||||
|
Interrupt(new_num); \
|
||||||
|
LOADIP; \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* All Byte genereal instructions */
|
||||||
|
#define ADDB(op1,op2,load,save) \
|
||||||
|
flags.var1.b=load(op1);flags.var2.b=op2; \
|
||||||
|
flags.result.b=flags.var1.b+flags.var2.b; \
|
||||||
|
save(op1,flags.result.b); \
|
||||||
|
flags.type=t_ADDb;
|
||||||
|
|
||||||
|
#define ADCB(op1,op2,load,save) \
|
||||||
|
flags.oldcf=get_CF(); \
|
||||||
|
flags.var1.b=load(op1);flags.var2.b=op2; \
|
||||||
|
flags.result.b=flags.var1.b+flags.var2.b+flags.oldcf; \
|
||||||
|
save(op1,flags.result.b); \
|
||||||
|
flags.type=t_ADCb;
|
||||||
|
|
||||||
|
#define SBBB(op1,op2,load,save) \
|
||||||
|
flags.oldcf=get_CF(); \
|
||||||
|
flags.var1.b=load(op1);flags.var2.b=op2; \
|
||||||
|
flags.result.b=flags.var1.b-(flags.var2.b+flags.oldcf); \
|
||||||
|
save(op1,flags.result.b); \
|
||||||
|
flags.type=t_SBBb;
|
||||||
|
|
||||||
|
#define SUBB(op1,op2,load,save) \
|
||||||
|
flags.var1.b=load(op1);flags.var2.b=op2; \
|
||||||
|
flags.result.b=flags.var1.b-flags.var2.b; \
|
||||||
|
save(op1,flags.result.b); \
|
||||||
|
flags.type=t_SUBb;
|
||||||
|
|
||||||
|
#define ORB(op1,op2,load,save) \
|
||||||
|
flags.var1.b=load(op1);flags.var2.b=op2; \
|
||||||
|
flags.result.b=flags.var1.b | flags.var2.b; \
|
||||||
|
save(op1,flags.result.b); \
|
||||||
|
flags.type=t_ORb;
|
||||||
|
|
||||||
|
#define XORB(op1,op2,load,save) \
|
||||||
|
flags.var1.b=load(op1);flags.var2.b=op2; \
|
||||||
|
flags.result.b=flags.var1.b ^ flags.var2.b; \
|
||||||
|
save(op1,flags.result.b); \
|
||||||
|
flags.type=t_XORb;
|
||||||
|
|
||||||
|
#define ANDB(op1,op2,load,save) \
|
||||||
|
flags.var1.b=load(op1);flags.var2.b=op2; \
|
||||||
|
flags.result.b=flags.var1.b & flags.var2.b; \
|
||||||
|
save(op1,flags.result.b); \
|
||||||
|
flags.type=t_ANDb;
|
||||||
|
|
||||||
|
#define CMPB(op1,op2,load,save) \
|
||||||
|
flags.var1.b=load(op1);flags.var2.b=op2; \
|
||||||
|
flags.result.b=flags.var1.b-flags.var2.b; \
|
||||||
|
flags.type=t_CMPb;
|
||||||
|
|
||||||
|
#define TESTB(op1,op2,load,save) \
|
||||||
|
flags.var1.b=load(op1);flags.var2.b=op2; \
|
||||||
|
flags.result.b=flags.var1.b & flags.var2.b; \
|
||||||
|
flags.type=t_TESTb;
|
||||||
|
|
||||||
|
/* All Word General instructions */
|
||||||
|
|
||||||
|
#define ADDW(op1,op2,load,save) \
|
||||||
|
flags.var1.w=load(op1);flags.var2.w=op2; \
|
||||||
|
flags.result.w=flags.var1.w+flags.var2.w; \
|
||||||
|
save(op1,flags.result.w); \
|
||||||
|
flags.type=t_ADDw;
|
||||||
|
|
||||||
|
#define ADCW(op1,op2,load,save) \
|
||||||
|
flags.oldcf=get_CF(); \
|
||||||
|
flags.var1.w=load(op1);flags.var2.w=op2; \
|
||||||
|
flags.result.w=flags.var1.w+flags.var2.w+flags.oldcf; \
|
||||||
|
save(op1,flags.result.w); \
|
||||||
|
flags.type=t_ADCw;
|
||||||
|
|
||||||
|
#define SBBW(op1,op2,load,save) \
|
||||||
|
flags.oldcf=get_CF(); \
|
||||||
|
flags.var1.w=load(op1);flags.var2.w=op2; \
|
||||||
|
flags.result.w=flags.var1.w-(flags.var2.w+flags.oldcf); \
|
||||||
|
save(op1,flags.result.w); \
|
||||||
|
flags.type=t_SBBw;
|
||||||
|
|
||||||
|
#define SUBW(op1,op2,load,save) \
|
||||||
|
flags.var1.w=load(op1);flags.var2.w=op2; \
|
||||||
|
flags.result.w=flags.var1.w-flags.var2.w; \
|
||||||
|
save(op1,flags.result.w); \
|
||||||
|
flags.type=t_SUBw;
|
||||||
|
|
||||||
|
#define ORW(op1,op2,load,save) \
|
||||||
|
flags.var1.w=load(op1);flags.var2.w=op2; \
|
||||||
|
flags.result.w=flags.var1.w | flags.var2.w; \
|
||||||
|
save(op1,flags.result.w); \
|
||||||
|
flags.type=t_ORw;
|
||||||
|
|
||||||
|
#define XORW(op1,op2,load,save) \
|
||||||
|
flags.var1.w=load(op1);flags.var2.w=op2; \
|
||||||
|
flags.result.w=flags.var1.w ^ flags.var2.w; \
|
||||||
|
save(op1,flags.result.w); \
|
||||||
|
flags.type=t_XORw;
|
||||||
|
|
||||||
|
#define ANDW(op1,op2,load,save) \
|
||||||
|
flags.var1.w=load(op1);flags.var2.w=op2; \
|
||||||
|
flags.result.w=flags.var1.w & flags.var2.w; \
|
||||||
|
save(op1,flags.result.w); \
|
||||||
|
flags.type=t_ANDw;
|
||||||
|
|
||||||
|
#define CMPW(op1,op2,load,save) \
|
||||||
|
flags.var1.w=load(op1);flags.var2.w=op2; \
|
||||||
|
flags.result.w=flags.var1.w-flags.var2.w; \
|
||||||
|
flags.type=t_CMPw;
|
||||||
|
|
||||||
|
#define TESTW(op1,op2,load,save) \
|
||||||
|
flags.var1.w=load(op1);flags.var2.w=op2; \
|
||||||
|
flags.result.w=flags.var1.w & flags.var2.w; \
|
||||||
|
flags.type=t_TESTw;
|
||||||
|
|
||||||
|
/* All DWORD General Instructions */
|
||||||
|
|
||||||
|
#define ADDD(op1,op2,load,save) \
|
||||||
|
flags.var1.d=load(op1);flags.var2.d=op2; \
|
||||||
|
flags.result.d=flags.var1.d+flags.var2.d; \
|
||||||
|
save(op1,flags.result.d); \
|
||||||
|
flags.type=t_ADDd;
|
||||||
|
|
||||||
|
#define ADCD(op1,op2,load,save) \
|
||||||
|
flags.oldcf=get_CF(); \
|
||||||
|
flags.var1.d=load(op1);flags.var2.d=op2; \
|
||||||
|
flags.result.d=flags.var1.d+flags.var2.d+flags.oldcf; \
|
||||||
|
save(op1,flags.result.d); \
|
||||||
|
flags.type=t_ADCd;
|
||||||
|
|
||||||
|
#define SBBD(op1,op2,load,save) \
|
||||||
|
flags.oldcf=get_CF(); \
|
||||||
|
flags.var1.d=load(op1);flags.var2.d=op2; \
|
||||||
|
flags.result.d=flags.var1.d-(flags.var2.d+flags.oldcf); \
|
||||||
|
save(op1,flags.result.d); \
|
||||||
|
flags.type=t_SBBd;
|
||||||
|
|
||||||
|
#define SUBD(op1,op2,load,save) \
|
||||||
|
flags.var1.d=load(op1);flags.var2.d=op2; \
|
||||||
|
flags.result.d=flags.var1.d-flags.var2.d; \
|
||||||
|
save(op1,flags.result.d); \
|
||||||
|
flags.type=t_SUBd;
|
||||||
|
|
||||||
|
#define ORD(op1,op2,load,save) \
|
||||||
|
flags.var1.d=load(op1);flags.var2.d=op2; \
|
||||||
|
flags.result.d=flags.var1.d | flags.var2.d; \
|
||||||
|
save(op1,flags.result.d); \
|
||||||
|
flags.type=t_ORd;
|
||||||
|
|
||||||
|
#define XORD(op1,op2,load,save) \
|
||||||
|
flags.var1.d=load(op1);flags.var2.d=op2; \
|
||||||
|
flags.result.d=flags.var1.d ^ flags.var2.d; \
|
||||||
|
save(op1,flags.result.d); \
|
||||||
|
flags.type=t_XORd;
|
||||||
|
|
||||||
|
#define ANDD(op1,op2,load,save) \
|
||||||
|
flags.var1.d=load(op1);flags.var2.d=op2; \
|
||||||
|
flags.result.d=flags.var1.d & flags.var2.d; \
|
||||||
|
save(op1,flags.result.d); \
|
||||||
|
flags.type=t_ANDd;
|
||||||
|
|
||||||
|
#define CMPD(op1,op2,load,save) \
|
||||||
|
flags.var1.d=load(op1);flags.var2.d=op2; \
|
||||||
|
flags.result.d=flags.var1.d-flags.var2.d; \
|
||||||
|
flags.type=t_CMPd;
|
||||||
|
|
||||||
|
|
||||||
|
#define TESTD(op1,op2,load,save) \
|
||||||
|
flags.var1.d=load(op1);flags.var2.d=op2; \
|
||||||
|
flags.result.d=flags.var1.d & flags.var2.d; \
|
||||||
|
flags.type=t_TESTd;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define INCB(op1,load,save) \
|
||||||
|
LoadCF;flags.result.b=load(op1)+1; \
|
||||||
|
save(op1,flags.result.b); \
|
||||||
|
flags.type=t_INCb; \
|
||||||
|
|
||||||
|
#define INCW(op1,load,save) \
|
||||||
|
LoadCF;flags.result.w=load(op1)+1; \
|
||||||
|
save(op1,flags.result.w); \
|
||||||
|
flags.type=t_INCw;
|
||||||
|
|
||||||
|
#define INCD(op1,load,save) \
|
||||||
|
LoadCF;flags.result.d=load(op1)+1; \
|
||||||
|
save(op1,flags.result.d); \
|
||||||
|
flags.type=t_INCd;
|
||||||
|
|
||||||
|
#define DECB(op1,load,save) \
|
||||||
|
LoadCF;flags.result.b=load(op1)-1; \
|
||||||
|
save(op1,flags.result.b); \
|
||||||
|
flags.type=t_DECb;
|
||||||
|
|
||||||
|
#define DECW(op1,load,save) \
|
||||||
|
LoadCF;flags.result.w=load(op1)-1; \
|
||||||
|
save(op1,flags.result.w); \
|
||||||
|
flags.type=t_DECw;
|
||||||
|
|
||||||
|
#define DECD(op1,load,save) \
|
||||||
|
LoadCF;flags.result.d=load(op1)-1; \
|
||||||
|
save(op1,flags.result.d); \
|
||||||
|
flags.type=t_DECd;
|
||||||
|
|
||||||
|
#define NOTDONE \
|
||||||
|
SUBIP(1);E_Exit("CPU:Opcode %2X Unhandled",Fetchb());
|
||||||
|
|
||||||
|
#define NOTDONE66 \
|
||||||
|
SUBIP(1);E_Exit("CPU:Opcode 66:%2X Unhandled",Fetchb());
|
||||||
|
|
||||||
|
|
||||||
|
//TODO Maybe make this into a bigger split up because of the rm >=0xc0 this seems make it a bit slower
|
||||||
|
//TODO set Zero and Sign flag in one run
|
||||||
|
#define ROLB(op1,op2,load,save) \
|
||||||
|
if (!(op2&0x07)) break; \
|
||||||
|
flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \
|
||||||
|
flags.var1.b=load(op1);flags.var2.b=op2&0x07; \
|
||||||
|
flags.result.b=(flags.var1.b << flags.var2.b) | \
|
||||||
|
(flags.var1.b >> (8-flags.var2.b)); \
|
||||||
|
save(op1,flags.result.b); \
|
||||||
|
flags.type=t_ROLb;
|
||||||
|
|
||||||
|
#define ROLW(op1,op2,load,save) \
|
||||||
|
if (!(op2&0x0F)) break; \
|
||||||
|
flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \
|
||||||
|
flags.var1.w=load(op1);flags.var2.b=op2&0x0F; \
|
||||||
|
flags.result.w=(flags.var1.w << flags.var2.b) | \
|
||||||
|
(flags.var1.w >> (16-flags.var2.b)); \
|
||||||
|
save(op1,flags.result.w); \
|
||||||
|
flags.type=t_ROLw;
|
||||||
|
|
||||||
|
|
||||||
|
#define ROLD(op1,op2,load,save) \
|
||||||
|
if (!(op2&0x0F)) break; \
|
||||||
|
flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \
|
||||||
|
flags.var1.d=load(op1);flags.var2.b=op2&0x0F; \
|
||||||
|
flags.result.d=(flags.var1.d << flags.var2.b) | \
|
||||||
|
(flags.var1.d >> (32-flags.var2.b)); \
|
||||||
|
save(op1,flags.result.d); \
|
||||||
|
flags.type=t_ROLd;
|
||||||
|
|
||||||
|
|
||||||
|
#define RORB(op1,op2,load,save) \
|
||||||
|
if (!(op2&0x07)) break; \
|
||||||
|
flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \
|
||||||
|
flags.var1.b=load(op1);flags.var2.b=op2&0x07; \
|
||||||
|
flags.result.b=(flags.var1.b >> flags.var2.b) | \
|
||||||
|
(flags.var1.b << (8-flags.var2.b)); \
|
||||||
|
save(op1,flags.result.b); \
|
||||||
|
flags.type=t_RORb;
|
||||||
|
|
||||||
|
|
||||||
|
#define RORW(op1,op2,load,save) \
|
||||||
|
if (!(op2&0x0F)) break; \
|
||||||
|
flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \
|
||||||
|
flags.var1.w=load(op1);flags.var2.b=op2&0x0F; \
|
||||||
|
flags.result.w=(flags.var1.w >> flags.var2.b) | \
|
||||||
|
(flags.var1.w << (16-flags.var2.b)); \
|
||||||
|
save(op1,flags.result.w); \
|
||||||
|
flags.type=t_RORw;
|
||||||
|
|
||||||
|
#define RORD(op1,op2,load,save) \
|
||||||
|
if (!(op2&0x0F)) break; \
|
||||||
|
flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \
|
||||||
|
flags.var1.d=load(op1);flags.var2.b=op2&0x0F; \
|
||||||
|
flags.result.d=(flags.var1.d >> flags.var2.b) | \
|
||||||
|
(flags.var1.d << (32-flags.var2.b)); \
|
||||||
|
save(op1,flags.result.d); \
|
||||||
|
flags.type=t_RORd;
|
||||||
|
|
||||||
|
#define RCLB(op1,op2,load,save) \
|
||||||
|
if (!(op2%9)) break; \
|
||||||
|
flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \
|
||||||
|
flags.cf=get_CF();flags.type=t_RCLb; \
|
||||||
|
flags.var1.b=load(op1);flags.var2.b=op2%9; \
|
||||||
|
flags.result.b=(flags.var1.b << flags.var2.b) | \
|
||||||
|
(flags.cf << (flags.var2.b-1)) | \
|
||||||
|
(flags.var1.b >> (9-flags.var2.b)); \
|
||||||
|
save(op1,flags.result.b);
|
||||||
|
|
||||||
|
#define RCLW(op1,op2,load,save) \
|
||||||
|
if (!(op2%17)) break; \
|
||||||
|
flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \
|
||||||
|
flags.cf=get_CF();flags.type=t_RCLw; \
|
||||||
|
flags.var1.w=load(op1);flags.var2.b=op2%17; \
|
||||||
|
flags.result.w=(flags.var1.w << flags.var2.b) | \
|
||||||
|
(flags.cf << (flags.var2.b-1)) | \
|
||||||
|
(flags.var1.w >> (17-flags.var2.b)); \
|
||||||
|
save(op1,flags.result.w);
|
||||||
|
|
||||||
|
#define RCLD(op1,op2,load,save) \
|
||||||
|
if (!op2) break; \
|
||||||
|
flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \
|
||||||
|
flags.cf=get_CF();flags.type=t_RCLd; \
|
||||||
|
flags.var1.d=load(op1);flags.var2.b=op2; \
|
||||||
|
if (flags.var2.b==1) { \
|
||||||
|
flags.result.d=flags.var1.d << 1 | flags.cf; \
|
||||||
|
} else { \
|
||||||
|
flags.result.d=(flags.var1.d << flags.var2.b) | \
|
||||||
|
(flags.cf << (flags.var2.b-1)) | \
|
||||||
|
(flags.var1.d >> (33-flags.var2.b)); \
|
||||||
|
} \
|
||||||
|
save(op1,flags.result.d);
|
||||||
|
|
||||||
|
#define RCRB(op1,op2,load,save) \
|
||||||
|
if (!(op2%9)) break; \
|
||||||
|
flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \
|
||||||
|
flags.cf=get_CF();flags.type=t_RCRb; \
|
||||||
|
flags.var1.b=load(op1);flags.var2.b=op2%9; \
|
||||||
|
flags.result.b=(flags.var1.b >> flags.var2.b) | \
|
||||||
|
(flags.cf << (8-flags.var2.b)) | \
|
||||||
|
(flags.var1.b << (9-flags.var2.b)); \
|
||||||
|
save(op1,flags.result.b);
|
||||||
|
|
||||||
|
#define RCRW(op1,op2,load,save) \
|
||||||
|
if (!(op2%17)) break; \
|
||||||
|
flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \
|
||||||
|
flags.cf=get_CF();flags.type=t_RCRw; \
|
||||||
|
flags.var1.w=load(op1);flags.var2.b=op2%17; \
|
||||||
|
flags.result.w=(flags.var1.w >> flags.var2.b) | \
|
||||||
|
(flags.cf << (16-flags.var2.b)) | \
|
||||||
|
(flags.var1.w << (17-flags.var2.b)); \
|
||||||
|
save(op1,flags.result.w);
|
||||||
|
|
||||||
|
|
||||||
|
#define RCRD(op1,op2,load,save) \
|
||||||
|
if (!op2) break; \
|
||||||
|
flags.zf=get_ZF();flags.sf=get_SF();flags.af=get_AF(); \
|
||||||
|
flags.cf=get_CF();flags.type=t_RCRd; \
|
||||||
|
flags.var1.d=load(op1);flags.var2.b=op2; \
|
||||||
|
if (flags.var2.b==1) { \
|
||||||
|
flags.result.d=flags.var1.d >> 1 | flags.cf << 31; \
|
||||||
|
} else { \
|
||||||
|
flags.result.d=(flags.var1.d >> flags.var2.b) | \
|
||||||
|
(flags.cf << (32-flags.var2.b)) | \
|
||||||
|
(flags.var1.d << (33-flags.var2.b)); \
|
||||||
|
} \
|
||||||
|
save(op1,flags.result.d);
|
||||||
|
|
||||||
|
#define SHLB(op1,op2,load,save) \
|
||||||
|
if (!op2) break; \
|
||||||
|
flags.var1.b=load(op1);flags.var2.b=op2; \
|
||||||
|
flags.result.b=flags.var1.b << flags.var2.b; \
|
||||||
|
save(op1,flags.result.b); \
|
||||||
|
flags.type=t_SHLb;
|
||||||
|
|
||||||
|
#define SHLW(op1,op2,load,save) \
|
||||||
|
if (!op2) break; \
|
||||||
|
flags.var1.w=load(op1);flags.var2.b=op2; \
|
||||||
|
flags.result.w=flags.var1.w << flags.var2.b; \
|
||||||
|
save(op1,flags.result.w); \
|
||||||
|
flags.type=t_SHLw;
|
||||||
|
|
||||||
|
#define SHLD(op1,op2,load,save) \
|
||||||
|
if (!op2) break; \
|
||||||
|
flags.var1.d=load(op1);flags.var2.b=op2; \
|
||||||
|
flags.result.d=flags.var1.d << flags.var2.b; \
|
||||||
|
save(op1,flags.result.d); \
|
||||||
|
flags.type=t_SHLd;
|
||||||
|
|
||||||
|
#define SHRB(op1,op2,load,save) \
|
||||||
|
if (!op2) break; \
|
||||||
|
flags.var1.b=load(op1);flags.var2.b=op2; \
|
||||||
|
flags.result.b=flags.var1.b >> flags.var2.b; \
|
||||||
|
save(op1,flags.result.b); \
|
||||||
|
flags.type=t_SHRb;
|
||||||
|
|
||||||
|
#define SHRW(op1,op2,load,save) \
|
||||||
|
if (!op2) break; \
|
||||||
|
flags.var1.w=load(op1);flags.var2.b=op2; \
|
||||||
|
flags.result.w=flags.var1.w >> flags.var2.b; \
|
||||||
|
save(op1,flags.result.w); \
|
||||||
|
flags.type=t_SHRw;
|
||||||
|
|
||||||
|
#define SHRD(op1,op2,load,save) \
|
||||||
|
if (!op2) break; \
|
||||||
|
flags.var1.d=load(op1);flags.var2.b=op2; \
|
||||||
|
flags.result.d=flags.var1.d >> flags.var2.b; \
|
||||||
|
save(op1,flags.result.d); \
|
||||||
|
flags.type=t_SHRd;
|
||||||
|
|
||||||
|
#define SARB(op1,op2,load,save) \
|
||||||
|
if (!op2) break; \
|
||||||
|
flags.var1.b=load(op1);flags.var2.b=op2; \
|
||||||
|
if (flags.var2.b>8) flags.var2.b=8; \
|
||||||
|
if (flags.var1.b & 0x80) { \
|
||||||
|
flags.result.b=(flags.var1.b >> flags.var2.b)| \
|
||||||
|
(0xff << (8 - flags.var2.b)); \
|
||||||
|
} else { \
|
||||||
|
flags.result.b=flags.var1.b >> flags.var2.b; \
|
||||||
|
} \
|
||||||
|
save(op1,flags.result.b); \
|
||||||
|
flags.type=t_SARb;
|
||||||
|
|
||||||
|
#define SARW(op1,op2,load,save) \
|
||||||
|
if (!op2) break; \
|
||||||
|
flags.var1.w=load(op1);flags.var2.b=op2; \
|
||||||
|
if (flags.var2.b>16) flags.var2.b=16; \
|
||||||
|
if (flags.var1.w & 0x8000) { \
|
||||||
|
flags.result.w=(flags.var1.w >> flags.var2.b)| \
|
||||||
|
(0xffff << (16 - flags.var2.b)); \
|
||||||
|
} else { \
|
||||||
|
flags.result.w=flags.var1.w >> flags.var2.b; \
|
||||||
|
} \
|
||||||
|
save(op1,flags.result.w); \
|
||||||
|
flags.type=t_SARw;
|
||||||
|
|
||||||
|
#define SARD(op1,op2,load,save) \
|
||||||
|
if (!op2) break; \
|
||||||
|
flags.var1.d=load(op1);flags.var2.b=op2; \
|
||||||
|
if (flags.var1.d & 0x80000000) { \
|
||||||
|
flags.result.d=(flags.var1.d >> flags.var2.b)| \
|
||||||
|
(0xffffffff << (32 - flags.var2.b)); \
|
||||||
|
} else { \
|
||||||
|
flags.result.d=flags.var1.d >> flags.var2.b; \
|
||||||
|
} \
|
||||||
|
save(op1,flags.result.d); \
|
||||||
|
flags.type=t_SARd;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define GRP2B(blah) \
|
||||||
|
{ \
|
||||||
|
GetRM; \
|
||||||
|
if (rm >= 0xc0) { \
|
||||||
|
GetEArb; \
|
||||||
|
Bit8u val=blah & 0x1f; \
|
||||||
|
switch (rm&0x38) { \
|
||||||
|
case 0x00:ROLB(*earb,val,LoadRb,SaveRb);break; \
|
||||||
|
case 0x08:RORB(*earb,val,LoadRb,SaveRb);break; \
|
||||||
|
case 0x10:RCLB(*earb,val,LoadRb,SaveRb);break; \
|
||||||
|
case 0x18:RCRB(*earb,val,LoadRb,SaveRb);break; \
|
||||||
|
case 0x20:/* SHL and SAL are the same */ \
|
||||||
|
case 0x30:SHLB(*earb,val,LoadRb,SaveRb);break; \
|
||||||
|
case 0x28:SHRB(*earb,val,LoadRb,SaveRb);break; \
|
||||||
|
case 0x38:SARB(*earb,val,LoadRb,SaveRb);break; \
|
||||||
|
} \
|
||||||
|
} else { \
|
||||||
|
GetEAa; \
|
||||||
|
Bit8u val=blah & 0x1f; \
|
||||||
|
switch (rm & 0x38) { \
|
||||||
|
case 0x00:ROLB(eaa,val,LoadMb,SaveMb);break; \
|
||||||
|
case 0x08:RORB(eaa,val,LoadMb,SaveMb);break; \
|
||||||
|
case 0x10:RCLB(eaa,val,LoadMb,SaveMb);break; \
|
||||||
|
case 0x18:RCRB(eaa,val,LoadMb,SaveMb);break; \
|
||||||
|
case 0x20:/* SHL and SAL are the same */ \
|
||||||
|
case 0x30:SHLB(eaa,val,LoadMb,SaveMb);break; \
|
||||||
|
case 0x28:SHRB(eaa,val,LoadMb,SaveMb);break; \
|
||||||
|
case 0x38:SARB(eaa,val,LoadMb,SaveMb);break; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define GRP2W(blah) \
|
||||||
|
{ \
|
||||||
|
GetRM; \
|
||||||
|
if (rm >= 0xc0) { \
|
||||||
|
GetEArw; \
|
||||||
|
Bit8u val=blah & 0x1f; \
|
||||||
|
switch (rm&0x38) { \
|
||||||
|
case 0x00:ROLW(*earw,val,LoadRw,SaveRw);break; \
|
||||||
|
case 0x08:RORW(*earw,val,LoadRw,SaveRw);break; \
|
||||||
|
case 0x10:RCLW(*earw,val,LoadRw,SaveRw);break; \
|
||||||
|
case 0x18:RCRW(*earw,val,LoadRw,SaveRw);break; \
|
||||||
|
case 0x20:/* SHL and SAL are the same */ \
|
||||||
|
case 0x30:SHLW(*earw,val,LoadRw,SaveRw);break; \
|
||||||
|
case 0x28:SHRW(*earw,val,LoadRw,SaveRw);break; \
|
||||||
|
case 0x38:SARW(*earw,val,LoadRw,SaveRw);break; \
|
||||||
|
} \
|
||||||
|
} else { \
|
||||||
|
GetEAa; \
|
||||||
|
Bit8u val=blah & 0x1f; \
|
||||||
|
switch (rm & 0x38) { \
|
||||||
|
case 0x00:ROLW(eaa,val,LoadMw,SaveMw);break; \
|
||||||
|
case 0x08:RORW(eaa,val,LoadMw,SaveMw);break; \
|
||||||
|
case 0x10:RCLW(eaa,val,LoadMw,SaveMw);break; \
|
||||||
|
case 0x18:RCRW(eaa,val,LoadMw,SaveMw);break; \
|
||||||
|
case 0x20:/* SHL and SAL are the same */ \
|
||||||
|
case 0x30:SHLW(eaa,val,LoadMw,SaveMw);break; \
|
||||||
|
case 0x28:SHRW(eaa,val,LoadMw,SaveMw);break; \
|
||||||
|
case 0x38:SARW(eaa,val,LoadMw,SaveMw);break; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define GRP2D(blah) \
|
||||||
|
{ \
|
||||||
|
GetRM; \
|
||||||
|
if (rm >= 0xc0) { \
|
||||||
|
GetEArd; \
|
||||||
|
Bit8u val=blah & 0x1f; \
|
||||||
|
switch (rm&0x38) { \
|
||||||
|
case 0x00:ROLD(*eard,val,LoadRd,SaveRd);break; \
|
||||||
|
case 0x08:RORD(*eard,val,LoadRd,SaveRd);break; \
|
||||||
|
case 0x10:RCLD(*eard,val,LoadRd,SaveRd);break; \
|
||||||
|
case 0x18:RCRD(*eard,val,LoadRd,SaveRd);break; \
|
||||||
|
case 0x20:/* SHL and SAL are the same */ \
|
||||||
|
case 0x30:SHLD(*eard,val,LoadRd,SaveRd);break; \
|
||||||
|
case 0x28:SHRD(*eard,val,LoadRd,SaveRd);break; \
|
||||||
|
case 0x38:SARD(*eard,val,LoadRd,SaveRd);break; \
|
||||||
|
} \
|
||||||
|
} else { \
|
||||||
|
GetEAa; \
|
||||||
|
Bit8u val=blah & 0x1f; \
|
||||||
|
switch (rm & 0x38) { \
|
||||||
|
case 0x00:ROLD(eaa,val,LoadMd,SaveMd);break; \
|
||||||
|
case 0x08:RORD(eaa,val,LoadMd,SaveMd);break; \
|
||||||
|
case 0x10:RCLD(eaa,val,LoadMd,SaveMd);break; \
|
||||||
|
case 0x18:RCRD(eaa,val,LoadMd,SaveMd);break; \
|
||||||
|
case 0x20:/* SHL and SAL are the same */ \
|
||||||
|
case 0x30:SHLD(eaa,val,LoadMd,SaveMd);break; \
|
||||||
|
case 0x28:SHRD(eaa,val,LoadMd,SaveMd);break; \
|
||||||
|
case 0x38:SARD(eaa,val,LoadMd,SaveMd);break; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* let's hope bochs has it correct with the higher than 16 shifts */
|
||||||
|
#define DSHLW(op1,op2,op3,load,save) \
|
||||||
|
flags.var1.d=(load(op1)<<16)|op2;flags.var2.b=op3; \
|
||||||
|
Bit32u tempd=flags.var1.d << flags.var2.b; \
|
||||||
|
if (flags.var2.b>16) tempd |= (op2 << (flags.var2.b - 16)); \
|
||||||
|
flags.result.w=(Bit16u)(tempd >> 16); \
|
||||||
|
save(op1,flags.result.w); \
|
||||||
|
flags.type=t_DSHLw;
|
||||||
|
|
||||||
|
#define DSHLD(op1,op2,op3,load,save) \
|
||||||
|
flags.var1.d=load(op1);flags.var2.b=op3; \
|
||||||
|
flags.result.d=(flags.var1.d << flags.var2.b) | (op2 >> (32-flags.var2.b)); \
|
||||||
|
save(op1,flags.result.d); \
|
||||||
|
flags.type=t_DSHLd;
|
||||||
|
|
||||||
|
#define DSHRW(op1,op2,op3,load,save) \
|
||||||
|
flags.var1.d=(load(op1)<<16)|op2;flags.var2.b=op3; \
|
||||||
|
Bit32u tempd=flags.var1.d >> flags.var2.b; \
|
||||||
|
if (flags.var2.b>16) tempd |= (op2 << (32-flags.var2.b )); \
|
||||||
|
flags.result.w=(Bit16u)(tempd); \
|
||||||
|
save(op1,flags.result.w); \
|
||||||
|
flags.type=t_DSHRw;
|
||||||
|
|
||||||
|
#define DSHRD(op1,op2,op3,load,save) \
|
||||||
|
flags.var1.d=load(op1);flags.var2.b=op3; \
|
||||||
|
flags.result.d=(flags.var1.d >> flags.var2.b) | (op2 << (32-flags.var2.b)); \
|
||||||
|
save(op1,flags.result.d); \
|
||||||
|
flags.type=t_DSHRd;
|
1488
src/cpu/core_16/main.h
Normal file
1488
src/cpu/core_16/main.h
Normal file
File diff suppressed because it is too large
Load Diff
469
src/cpu/core_16/prefix_66.h
Normal file
469
src/cpu/core_16/prefix_66.h
Normal file
@ -0,0 +1,469 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2002 The DOSBox Team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
restart_66:
|
||||||
|
switch(Fetchb()) {
|
||||||
|
case 0x01: /* ADD Ed,Gd */
|
||||||
|
RMEdGd(ADDD);break;
|
||||||
|
case 0x03: /* ADD Gd,Ed */
|
||||||
|
RMGdEd(ADDD);break;
|
||||||
|
case 0x05: /* ADD EAX,Id */
|
||||||
|
EAXId(ADDD);break;
|
||||||
|
case 0x09: /* OR Ew,Gw */
|
||||||
|
RMEdGd(ORD);break;
|
||||||
|
case 0x0b: /* OR Gd,Ed */
|
||||||
|
RMGdEd(ORD);break;
|
||||||
|
case 0x0d: /* OR EAX,Id */
|
||||||
|
EAXId(ORD);break;
|
||||||
|
case 0x0f: /* 2 Byte opcodes */
|
||||||
|
#include "prefix_66_of.h"
|
||||||
|
break;
|
||||||
|
case 0x11: /* ADC Ed,Gd */
|
||||||
|
RMEdGd(ADCD);break;
|
||||||
|
case 0x13: /* ADC Gd,Ed */
|
||||||
|
RMGdEd(ADCD);break;
|
||||||
|
case 0x15: /* ADC EAX,Id */
|
||||||
|
EAXId(ADCD);break;
|
||||||
|
case 0x19: /* SBB Ed,Gd */
|
||||||
|
RMEdGd(SBBD);break;
|
||||||
|
case 0x1b: /* SBB Gd,Ed */
|
||||||
|
RMGdEd(SBBD);break;
|
||||||
|
case 0x1d: /* SBB EAX,Id */
|
||||||
|
EAXId(SBBD);break;
|
||||||
|
case 0x21: /* AND Ed,Gd */
|
||||||
|
RMEdGd(ANDD);break;
|
||||||
|
case 0x23: /* AND Gd,Ed */
|
||||||
|
RMGdEd(ANDD);break;
|
||||||
|
case 0x25: /* AND EAX,Id */
|
||||||
|
EAXId(ANDD);break;
|
||||||
|
case 0x29: /* SUB Ed,Gd */
|
||||||
|
RMEdGd(SUBD);break;
|
||||||
|
case 0x2b: /* SUB Gd,Ed */
|
||||||
|
RMGdEd(SUBD);break;
|
||||||
|
case 0x2d: /* SUB EAX,Id */
|
||||||
|
EAXId(SUBD);break;
|
||||||
|
case 0x31: /* XOR Ed,Gd */
|
||||||
|
RMEdGd(XORD);break;
|
||||||
|
case 0x33: /* XOR Gd,Ed */
|
||||||
|
RMGdEd(XORD);break;
|
||||||
|
case 0x35: /* XOR EAX,Id */
|
||||||
|
EAXId(XORD);break;
|
||||||
|
case 0x39: /* CMP Ed,Gd */
|
||||||
|
RMEdGd(CMPD);break;
|
||||||
|
case 0x3b: /* CMP Gd,Ed */
|
||||||
|
RMGdEd(CMPD);break;
|
||||||
|
case 0x3d: /* CMP EAX,Id */
|
||||||
|
EAXId(CMPD);break;
|
||||||
|
|
||||||
|
|
||||||
|
case 0x26: /* SEG ES: */
|
||||||
|
SegPrefix_66(es);break;
|
||||||
|
case 0x2e: /* SEG CS: */
|
||||||
|
SegPrefix_66(cs);break;
|
||||||
|
case 0x36: /* SEG SS: */
|
||||||
|
SegPrefix_66(ss);break;
|
||||||
|
case 0x3e: /* SEG DS: */
|
||||||
|
SegPrefix_66(ds);break;
|
||||||
|
case 0x40: /* INC EAX */
|
||||||
|
INCD(reg_eax,LoadRd,SaveRd);break;
|
||||||
|
case 0x41: /* INC ECX */
|
||||||
|
INCD(reg_ecx,LoadRd,SaveRd);break;
|
||||||
|
case 0x42: /* INC EDX */
|
||||||
|
INCD(reg_edx,LoadRd,SaveRd);break;
|
||||||
|
case 0x43: /* INC EBX */
|
||||||
|
INCD(reg_ebx,LoadRd,SaveRd);break;
|
||||||
|
case 0x44: /* INC ESP */
|
||||||
|
INCD(reg_esp,LoadRd,SaveRd);break;
|
||||||
|
case 0x45: /* INC EBP */
|
||||||
|
INCD(reg_ebp,LoadRd,SaveRd);break;
|
||||||
|
case 0x46: /* INC ESI */
|
||||||
|
INCD(reg_esi,LoadRd,SaveRd);break;
|
||||||
|
case 0x47: /* INC EDI */
|
||||||
|
INCD(reg_edi,LoadRd,SaveRd);break;
|
||||||
|
case 0x48: /* DEC EAX */
|
||||||
|
DECD(reg_eax,LoadRd,SaveRd);break;
|
||||||
|
case 0x49: /* DEC ECX */
|
||||||
|
DECD(reg_ecx,LoadRd,SaveRd);break;
|
||||||
|
case 0x4a: /* DEC EDX */
|
||||||
|
DECD(reg_edx,LoadRd,SaveRd);break;
|
||||||
|
case 0x4b: /* DEC EBX */
|
||||||
|
DECD(reg_ebx,LoadRd,SaveRd);break;
|
||||||
|
case 0x4c: /* DEC ESP */
|
||||||
|
DECD(reg_esp,LoadRd,SaveRd);break;
|
||||||
|
case 0x4d: /* DEC EBP */
|
||||||
|
DECD(reg_ebp,LoadRd,SaveRd);break;
|
||||||
|
case 0x4e: /* DEC ESI */
|
||||||
|
DECD(reg_esi,LoadRd,SaveRd);break;
|
||||||
|
case 0x4f: /* DEC EDI */
|
||||||
|
DECD(reg_edi,LoadRd,SaveRd);break;
|
||||||
|
case 0x50: /* PUSH EAX */
|
||||||
|
Push_32(reg_eax);break;
|
||||||
|
case 0x51: /* PUSH ECX */
|
||||||
|
Push_32(reg_ecx);break;
|
||||||
|
case 0x52: /* PUSH EDX */
|
||||||
|
Push_32(reg_edx);break;
|
||||||
|
case 0x53: /* PUSH EBX */
|
||||||
|
Push_32(reg_ebx);break;
|
||||||
|
case 0x54: /* PUSH ESP */
|
||||||
|
Push_32(reg_esp);break;
|
||||||
|
case 0x55: /* PUSH EBP */
|
||||||
|
Push_32(reg_ebp);break;
|
||||||
|
case 0x56: /* PUSH ESI */
|
||||||
|
Push_32(reg_esi);break;
|
||||||
|
case 0x57: /* PUSH EDI */
|
||||||
|
Push_32(reg_edi);break;
|
||||||
|
case 0x58: /* POP EAX */
|
||||||
|
reg_eax=Pop_32();break;
|
||||||
|
case 0x59: /* POP ECX */
|
||||||
|
reg_ecx=Pop_32();break;
|
||||||
|
case 0x5a: /* POP EDX */
|
||||||
|
reg_edx=Pop_32();break;
|
||||||
|
case 0x5b: /* POP EBX */
|
||||||
|
reg_ebx=Pop_32();break;
|
||||||
|
case 0x5c: /* POP ESP */
|
||||||
|
reg_esp=Pop_32();break;
|
||||||
|
case 0x5d: /* POP EBP */
|
||||||
|
reg_ebp=Pop_32();break;
|
||||||
|
case 0x5e: /* POP ESI */
|
||||||
|
reg_esi=Pop_32();break;
|
||||||
|
case 0x5f: /* POP EDI */
|
||||||
|
reg_edi=Pop_32();break;
|
||||||
|
case 0x60: /* PUSHAD */
|
||||||
|
Push_32(reg_eax);Push_32(reg_ecx);Push_32(reg_edx);Push_32(reg_ebx);
|
||||||
|
Push_32(reg_esp);Push_32(reg_ebp);Push_32(reg_esi);Push_32(reg_edi);
|
||||||
|
break;
|
||||||
|
case 0x61: /* POPAD */
|
||||||
|
reg_edi=Pop_32();reg_edi=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 0x68: /* PUSH Id */
|
||||||
|
Push_32(Fetchd());break;
|
||||||
|
case 0x69: /* IMUL Gd,Ed,Id */
|
||||||
|
{
|
||||||
|
GetRMrd;
|
||||||
|
Bit64s res;
|
||||||
|
if (rm >= 0xc0 ) {GetEArd;res=(Bit64s)(*eards) * (Bit64s)Fetchds();}
|
||||||
|
else {GetEAa;res=(Bit64s)LoadMds(eaa) * (Bit64s)Fetchds();}
|
||||||
|
*rmrd=(Bit32s)(res);
|
||||||
|
flags.type=t_MUL;
|
||||||
|
if ((res>-((Bit64s)(2147483647)+1)) && (res<(Bit64s)2147483647)) {flags.cf=false;flags.of=false;}
|
||||||
|
else {flags.cf=true;flags.of=true;}
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
case 0x6a: /* PUSH Ib */
|
||||||
|
Push_32(Fetchbs());break;
|
||||||
|
case 0x81: /* Grpl Ed,Id */
|
||||||
|
{
|
||||||
|
GetRM;
|
||||||
|
if (rm>= 0xc0) {
|
||||||
|
GetEArd;Bit32u id=Fetchd();
|
||||||
|
switch (rm & 0x38) {
|
||||||
|
case 0x00:ADDD(*eard,id,LoadRd,SaveRd);break;
|
||||||
|
case 0x08: ORD(*eard,id,LoadRd,SaveRd);break;
|
||||||
|
case 0x10:ADCD(*eard,id,LoadRd,SaveRd);break;
|
||||||
|
case 0x18:SBBD(*eard,id,LoadRd,SaveRd);break;
|
||||||
|
case 0x20:ANDD(*eard,id,LoadRd,SaveRd);break;
|
||||||
|
case 0x28:SUBD(*eard,id,LoadRd,SaveRd);break;
|
||||||
|
case 0x30:XORD(*eard,id,LoadRd,SaveRd);break;
|
||||||
|
case 0x38:CMPD(*eard,id,LoadRd,SaveRd);break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
GetEAa;Bit32u id=Fetchb();
|
||||||
|
switch (rm & 0x38) {
|
||||||
|
case 0x00:ADDD(eaa,id,LoadMd,SaveMd);break;
|
||||||
|
case 0x08: ORD(eaa,id,LoadMd,SaveMd);break;
|
||||||
|
case 0x10:ADCD(eaa,id,LoadMd,SaveMd);break;
|
||||||
|
case 0x18:SBBD(eaa,id,LoadMd,SaveMd);break;
|
||||||
|
case 0x20:ANDD(eaa,id,LoadMd,SaveMd);break;
|
||||||
|
case 0x28:SUBD(eaa,id,LoadMd,SaveMd);break;
|
||||||
|
case 0x30:XORD(eaa,id,LoadMd,SaveMd);break;
|
||||||
|
case 0x38:CMPD(eaa,id,LoadMd,SaveMd);break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x83: /* Grpl Ed,Ix */
|
||||||
|
{
|
||||||
|
GetRM;
|
||||||
|
if (rm>= 0xc0) {
|
||||||
|
GetEArd;Bit32u id=(Bit32s)Fetchbs();
|
||||||
|
switch (rm & 0x38) {
|
||||||
|
case 0x00:ADDD(*eard,id,LoadRd,SaveRd);break;
|
||||||
|
case 0x08: ORD(*eard,id,LoadRd,SaveRd);break;
|
||||||
|
case 0x10:ADCD(*eard,id,LoadRd,SaveRd);break;
|
||||||
|
case 0x18:SBBD(*eard,id,LoadRd,SaveRd);break;
|
||||||
|
case 0x20:ANDD(*eard,id,LoadRd,SaveRd);break;
|
||||||
|
case 0x28:SUBD(*eard,id,LoadRd,SaveRd);break;
|
||||||
|
case 0x30:XORD(*eard,id,LoadRd,SaveRd);break;
|
||||||
|
case 0x38:CMPD(*eard,id,LoadRd,SaveRd);break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
GetEAa;Bit32u id=(Bit32s)Fetchbs();
|
||||||
|
switch (rm & 0x38) {
|
||||||
|
case 0x00:ADDD(eaa,id,LoadMd,SaveMd);break;
|
||||||
|
case 0x08: ORD(eaa,id,LoadMd,SaveMd);break;
|
||||||
|
case 0x10:ADCD(eaa,id,LoadMd,SaveMd);break;
|
||||||
|
case 0x18:SBBD(eaa,id,LoadMd,SaveMd);break;
|
||||||
|
case 0x20:ANDD(eaa,id,LoadMd,SaveMd);break;
|
||||||
|
case 0x28:SUBD(eaa,id,LoadMd,SaveMd);break;
|
||||||
|
case 0x30:XORD(eaa,id,LoadMd,SaveMd);break;
|
||||||
|
case 0x38:CMPD(eaa,id,LoadMd,SaveMd);break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x8f: /* POP Ed */
|
||||||
|
{
|
||||||
|
GetRM;
|
||||||
|
if (rm >= 0xc0 ) {GetEArd;*eard=Pop_32();}
|
||||||
|
else {GetEAa;SaveMd(eaa,Pop_32());}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 0x89: /* MOV Ed,Gd */
|
||||||
|
{
|
||||||
|
GetRMrd;
|
||||||
|
if (rm >= 0xc0 ) {GetEArd;*eard=*rmrd;}
|
||||||
|
else {GetEAa;SaveMd(eaa,*rmrd);}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x99: /* CDQ */
|
||||||
|
if (reg_eax & 0x80000000) reg_edx=0xffffffff;
|
||||||
|
else reg_edx=0;
|
||||||
|
break;
|
||||||
|
case 0x8b: /* MOV Gd,Ed */
|
||||||
|
{
|
||||||
|
GetRMrd;
|
||||||
|
if (rm >= 0xc0 ) {GetEArd;*rmrd=*eard;}
|
||||||
|
else {GetEAa;*rmrd=LoadMd(eaa);}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x8c:
|
||||||
|
LOG_WARN("CPU:66:8c looped back");
|
||||||
|
break;
|
||||||
|
case 0x9c: /* PUSHFD */
|
||||||
|
{
|
||||||
|
Bit32u pflags=
|
||||||
|
(get_CF() << 0) | (get_PF() << 2) | (get_AF() << 4) |
|
||||||
|
(get_ZF() << 6) | (get_SF() << 7) | (flags.tf << 8) |
|
||||||
|
(flags.intf << 9) |(flags.df << 10) | (get_OF() << 11) |
|
||||||
|
(flags.io << 12) | (flags.nt <<14);
|
||||||
|
Push_32(pflags);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x9d: /* POPFD */
|
||||||
|
{
|
||||||
|
Save_Flagsw((Bit16u)(Pop_32()&0xffff));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0xa1: /* MOV EAX,Ow */
|
||||||
|
if (segprefix_on) {
|
||||||
|
reg_eax=LoadMd(segprefix_base+Fetchw());
|
||||||
|
SegPrefixReset;
|
||||||
|
} else {
|
||||||
|
reg_eax=LoadMd(SegBase(ds)+Fetchw());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0xa3: /* MOV Ow,EAX */
|
||||||
|
if (segprefix_on) {
|
||||||
|
SaveMd((segprefix_base+Fetchw()),reg_eax);
|
||||||
|
SegPrefixReset;
|
||||||
|
} else {
|
||||||
|
SaveMd((SegBase(ds)+Fetchw()),reg_eax);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0xa5: /* MOVSD */
|
||||||
|
{
|
||||||
|
stringSI;stringDI;SaveMd(to,LoadMd(from));
|
||||||
|
if (flags.df) { reg_si-=4;reg_di-=4; }
|
||||||
|
else { reg_si+=4;reg_di+=4;}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0xab: /* STOSD */
|
||||||
|
{
|
||||||
|
stringDI;
|
||||||
|
SaveMd(to,reg_eax);
|
||||||
|
if (flags.df) { reg_di-=4; }
|
||||||
|
else {reg_di+=4;}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0xad: /* LODSD */
|
||||||
|
{
|
||||||
|
stringSI;
|
||||||
|
reg_eax=LoadMd(from);
|
||||||
|
if (flags.df) { reg_si-=4;}
|
||||||
|
else {reg_si+=4;}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0xaf: /* SCASD */
|
||||||
|
{
|
||||||
|
stringDI;
|
||||||
|
CMPD(reg_eax,LoadMd(to),LoadRd,0);
|
||||||
|
if (flags.df) { reg_di-=4; }
|
||||||
|
else {reg_di+=4;}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0xb8: /* MOV EAX,Id */
|
||||||
|
reg_eax=Fetchd();break;
|
||||||
|
case 0xb9: /* MOV ECX,Id */
|
||||||
|
reg_ecx=Fetchd();break;
|
||||||
|
case 0xba: /* MOV EDX,Iw */
|
||||||
|
reg_edx=Fetchd();break;
|
||||||
|
case 0xbb: /* MOV EBX,Id */
|
||||||
|
reg_ebx=Fetchd();break;
|
||||||
|
case 0xbc: /* MOV ESP,Id */
|
||||||
|
reg_esp=Fetchd();break;
|
||||||
|
case 0xbd: /* MOV EBP.Id */
|
||||||
|
reg_ebp=Fetchd();break;
|
||||||
|
case 0xbe: /* MOV ESI,Id */
|
||||||
|
reg_esi=Fetchd();break;
|
||||||
|
case 0xbf: /* MOV EDI,Id */
|
||||||
|
reg_edi=Fetchd();break;
|
||||||
|
case 0xc1: /* GRP2 Ed,Ib */
|
||||||
|
GRP2D(Fetchb());break;
|
||||||
|
case 0xc7: /* MOV Ed,Id */
|
||||||
|
{
|
||||||
|
GetRM;
|
||||||
|
if (rm>0xc0) {GetEArd;*eard=Fetchd();}
|
||||||
|
else {GetEAa;SaveMd(eaa,Fetchd());}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0xd1: /* GRP2 Ed,1 */
|
||||||
|
GRP2D(1);break;
|
||||||
|
case 0xd3: /* GRP2 Ed,CL */
|
||||||
|
GRP2D(reg_cl);break;
|
||||||
|
case 0xf7: /* GRP3 Ed(,Id) */
|
||||||
|
{
|
||||||
|
union { Bit64u u;Bit64s s;} temp;
|
||||||
|
union {Bit64u u;Bit64s s;} quotient;
|
||||||
|
GetRM;
|
||||||
|
switch (rm & 0x38) {
|
||||||
|
case 0x00: /* TEST Ed,Id */
|
||||||
|
case 0x08: /* TEST Ed,Id Undocumented*/
|
||||||
|
{
|
||||||
|
if (rm >= 0xc0 ) {GetEArd;TESTD(*eard,Fetchd(),LoadRd,SaveRd);}
|
||||||
|
else {GetEAa;TESTD(eaa,Fetchd(),LoadMd,SaveMd);}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x10: /* NOT Ed */
|
||||||
|
{
|
||||||
|
if (rm >= 0xc0 ) {GetEArd;*eard=~*eard;}
|
||||||
|
else {GetEAa;SaveMd(eaa,~LoadMd(eaa));}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x18: /* NEG Ed */
|
||||||
|
{
|
||||||
|
flags.type=t_NEGd;
|
||||||
|
if (rm >= 0xc0 ) {
|
||||||
|
GetEArd;flags.var1.d=*eard;flags.result.d=0-flags.var1.d;
|
||||||
|
*eard=flags.result.d;
|
||||||
|
} else {
|
||||||
|
GetEAa;flags.var1.d=LoadMd(eaa);flags.result.d=0-flags.var1.d;
|
||||||
|
SaveMd(eaa,flags.result.d);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x20: /* MUL EAX,Ed */
|
||||||
|
{
|
||||||
|
flags.type=t_MUL;
|
||||||
|
if (rm >= 0xc0 ) {GetEArd;temp.u=(Bit64s)reg_eax * (Bit64u)(*eard);}
|
||||||
|
else {GetEAa;temp.u=(Bit64u)reg_eax * (Bit64u)LoadMd(eaa);}
|
||||||
|
reg_eax=(Bit32u)(temp.u & 0xffffffff);reg_eax=(Bit32u)(temp.u >> 32);
|
||||||
|
flags.cf=flags.of=(reg_edx !=0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x28: /* IMUL EAX,Ed */
|
||||||
|
{
|
||||||
|
flags.type=t_MUL;
|
||||||
|
if (rm >= 0xc0 ) {GetEArd;temp.s=(Bit64s)reg_eax * (Bit64s)(*eards);}
|
||||||
|
else {GetEAa;temp.s=(Bit64s)reg_eax * (Bit64s)LoadMds(eaa);}
|
||||||
|
reg_eax=Bit32u(temp.u & 0xffffffff);reg_edx=(Bit32u)(temp.u >> 32);
|
||||||
|
if ( (reg_edx==0xffffffff) && (reg_eax & 0x80000000) ) {
|
||||||
|
flags.cf=flags.of=false;
|
||||||
|
} else if ( (reg_edx==0x00000000) && (reg_eax<0x80000000) ) {
|
||||||
|
flags.cf=flags.of=false;
|
||||||
|
} else {
|
||||||
|
flags.cf=flags.of=true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x30: /* DIV Ed */
|
||||||
|
{
|
||||||
|
// flags.type=t_DIV;
|
||||||
|
Bit32u val;
|
||||||
|
if (rm >= 0xc0 ) {GetEArd;val=*eard;}
|
||||||
|
else {GetEAa;val=LoadMd(eaa);}
|
||||||
|
if (val==0) {Interrupt(0);break;}
|
||||||
|
temp.u=(((Bit64u)reg_edx)<<32)|reg_eax;
|
||||||
|
quotient.u=temp.u/val;
|
||||||
|
reg_edx=(Bit32u)(temp.u % val);
|
||||||
|
reg_eax=(Bit32u)(quotient.u & 0xffffffff);
|
||||||
|
if (quotient.u>0xffffffff)
|
||||||
|
Interrupt(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0x38: /* IDIV Ed */
|
||||||
|
{
|
||||||
|
// flags.type=t_DIV;
|
||||||
|
Bit32s val;
|
||||||
|
if (rm >= 0xc0 ) {GetEArd;val=*eards;}
|
||||||
|
else {GetEAa;val=LoadMds(eaa);}
|
||||||
|
if (val==0) {Interrupt(0);break;}
|
||||||
|
temp.s=(((Bit64u)reg_edx)<<32)|reg_eax;
|
||||||
|
quotient.s=(temp.s/val);
|
||||||
|
reg_edx=(Bit32s)(temp.s % val);
|
||||||
|
reg_eax=(Bit32s)(quotient.s);
|
||||||
|
if (quotient.s!=(Bit32s)reg_eax)
|
||||||
|
Interrupt(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0xff: /* Group 5 */
|
||||||
|
{
|
||||||
|
GetRM;
|
||||||
|
switch (rm & 0x38) {
|
||||||
|
case 0x00: /* INC Ew */
|
||||||
|
flags.cf=get_CF();flags.type=t_INCd;
|
||||||
|
if (rm >= 0xc0 ) {GetEArd;flags.result.d=*eard+=1;}
|
||||||
|
else {GetEAa;flags.result.d=LoadMd(eaa)+1;SaveMd(eaa,flags.result.d);}
|
||||||
|
break;
|
||||||
|
case 0x08: /* DEC Ew */
|
||||||
|
flags.cf=get_CF();flags.type=t_DECd;
|
||||||
|
if (rm >= 0xc0 ) {GetEArd;flags.result.d=*eard-=1;}
|
||||||
|
else {GetEAa;flags.result.d=LoadMd(eaa)-1;SaveMd(eaa,flags.result.d);}
|
||||||
|
break;
|
||||||
|
case 0x30: /* Push Ed */
|
||||||
|
if (rm >= 0xc0 ) {GetEArd;Push_32(*eard);}
|
||||||
|
else {GetEAa;Push_32(LoadMd(eaa));}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
E_Exit("CPU:66:GRP5:Illegal call %2X",rm & 0x38);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
NOTDONE66;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
124
src/cpu/core_16/prefix_66_of.h
Normal file
124
src/cpu/core_16/prefix_66_of.h
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2002 The DOSBox Team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
switch (Fetchb()) {
|
||||||
|
|
||||||
|
|
||||||
|
case 0xa4: /* SHLD Ed,Gd,Ib */
|
||||||
|
{
|
||||||
|
GetRMrd;
|
||||||
|
if (rm >= 0xc0 ) {GetEArd;DSHLD(*eard,*rmrd,Fetchb(),LoadRd,SaveRd);}
|
||||||
|
else {GetEAa;DSHLD(eaa,*rmrd,Fetchb(),LoadMd,SaveMd);}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0xac: /* SHRD Ed,Gd,Ib */
|
||||||
|
{
|
||||||
|
GetRMrd;
|
||||||
|
if (rm >= 0xc0 ) {GetEArd;DSHRD(*eard,*rmrd,Fetchb(),LoadRd,SaveRd);}
|
||||||
|
else {GetEAa;DSHRD(eaa,*rmrd,Fetchb(),LoadMd,SaveMd);}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0xb6: /* MOVZX Gd,Eb */
|
||||||
|
{
|
||||||
|
GetRMrd;
|
||||||
|
if (rm >= 0xc0 ) {GetEArb;*rmrd=*earb;}
|
||||||
|
else {GetEAa;*rmrd=LoadMb(eaa);}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0xaf: /* IMUL Gd,Ed */
|
||||||
|
{
|
||||||
|
GetRMrd;
|
||||||
|
Bit64s res;
|
||||||
|
if (rm >= 0xc0 ) {GetEArd;res=(Bit64s)(*rmrd) * (Bit64s)(*eards);}
|
||||||
|
else {GetEAa;res=(Bit64s)(*rmrd) * (Bit64s)LoadMds(eaa);}
|
||||||
|
*rmrd=(Bit32s)(res);
|
||||||
|
flags.type=t_MUL;
|
||||||
|
if ((res>-((Bit64s)(2147483647)+1)) && (res<(Bit64s)2147483647)) {flags.cf=false;flags.of=false;}
|
||||||
|
else {flags.cf=true;flags.of=true;}
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
case 0xb7: /* MOVXZ Gd,Ew */
|
||||||
|
{
|
||||||
|
GetRMrd;
|
||||||
|
if (rm >= 0xc0 ) {GetEArw;*rmrd=*earw;}
|
||||||
|
else {GetEAa;*rmrd=LoadMw(eaa);}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0xba: /* GRP8 Ed,Ib */
|
||||||
|
{
|
||||||
|
GetRM;
|
||||||
|
if (rm >= 0xc0 ) {
|
||||||
|
GetEArd;
|
||||||
|
Bit32u mask=1 << (Fetchb() & 31);
|
||||||
|
flags.cf=(*eard & mask)>0;
|
||||||
|
switch (rm & 0x38) {
|
||||||
|
case 0x20: /* BT */
|
||||||
|
break;
|
||||||
|
case 0x28: /* BTS */
|
||||||
|
*eard|=mask;
|
||||||
|
break;
|
||||||
|
case 0x30: /* BTR */
|
||||||
|
*eard&=~mask;
|
||||||
|
break;
|
||||||
|
case 0x38: /* BTC */
|
||||||
|
if (flags.cf) *eard&=~mask;
|
||||||
|
else *eard|=mask;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
GetEAa;Bit32u old=LoadMd(eaa);
|
||||||
|
Bit32u mask=1 << (Fetchb() & 31);
|
||||||
|
flags.cf=(old & mask)>0;
|
||||||
|
switch (rm & 0x38) {
|
||||||
|
case 0x20: /* BT */
|
||||||
|
break;
|
||||||
|
case 0x28: /* BTS */
|
||||||
|
SaveMd(eaa,old|mask);
|
||||||
|
break;
|
||||||
|
case 0x30: /* BTR */
|
||||||
|
SaveMd(eaa,old & ~mask);
|
||||||
|
break;
|
||||||
|
case 0x38: /* BTC */
|
||||||
|
if (flags.cf) old&=~mask;
|
||||||
|
else old|=mask;
|
||||||
|
SaveMd(eaa,old);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (flags.type!=t_CF) flags.prev_type=flags.type;
|
||||||
|
flags.type=t_CF;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0xbe: /* MOVSX Gd,Eb */
|
||||||
|
{
|
||||||
|
GetRMrd;
|
||||||
|
if (rm >= 0xc0 ) {GetEArb;*rmrd=*earbs;}
|
||||||
|
else {GetEAa;*rmrd=LoadMbs(eaa);}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0xbf: /* MOVSX Gd,Ew */
|
||||||
|
{
|
||||||
|
GetRMrd;
|
||||||
|
if (rm >= 0xc0 ) {GetEArw;*rmrd=*earws;}
|
||||||
|
else {GetEAa;*rmrd=LoadMws(eaa);}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
SUBIP(1);
|
||||||
|
E_Exit("CPU:Opcode 66:0F:%2X Unhandled",Fetchb());
|
||||||
|
}
|
188
src/cpu/core_16/prefix_of.h
Normal file
188
src/cpu/core_16/prefix_of.h
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2002 The DOSBox Team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
switch(Fetchb()) {
|
||||||
|
case 0x01: /* GRP 7 */
|
||||||
|
{
|
||||||
|
GetRM;
|
||||||
|
switch (rm & 0x38) {
|
||||||
|
case 0x20: /* SMSW */
|
||||||
|
/* Let's seriously fake this call */
|
||||||
|
if (rm>0xc0) {GetEArw;*earw=0;}
|
||||||
|
else {GetEAa;SaveMw(eaa,0);}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
E_Exit("CPU:GRP7:Illegal call %2X",rm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x80: /* JO */
|
||||||
|
JumpSIw(get_OF());break;
|
||||||
|
case 0x81: /* JNO */
|
||||||
|
JumpSIw(!get_OF());break;
|
||||||
|
case 0x82: /* JB */
|
||||||
|
JumpSIw(get_CF());break;
|
||||||
|
case 0x83: /* JNB */
|
||||||
|
JumpSIw(!get_CF());break;
|
||||||
|
case 0x84: /* JZ */
|
||||||
|
JumpSIw(get_ZF());break;
|
||||||
|
case 0x85: /* JNZ */
|
||||||
|
JumpSIw(!get_ZF()); break;
|
||||||
|
case 0x86: /* JBE */
|
||||||
|
JumpSIw(get_CF() || get_ZF());break;
|
||||||
|
case 0x87: /* JNBE */
|
||||||
|
JumpSIw(!get_CF() && !get_ZF());break;
|
||||||
|
case 0x88: /* JS */
|
||||||
|
JumpSIw(get_SF());break;
|
||||||
|
case 0x89: /* JNS */
|
||||||
|
JumpSIw(!get_SF());break;
|
||||||
|
case 0x8a: /* JP */
|
||||||
|
JumpSIw(get_PF());break;
|
||||||
|
case 0x8b: /* JNP */
|
||||||
|
JumpSIw(!get_PF());break;
|
||||||
|
case 0x8c: /* JL */
|
||||||
|
JumpSIw(get_SF() != get_OF());break;
|
||||||
|
case 0x8d: /* JNL */
|
||||||
|
JumpSIw(get_SF() == get_OF());break;
|
||||||
|
case 0x8e: /* JLE */
|
||||||
|
JumpSIw(get_ZF() || (get_SF() != get_OF()));break;
|
||||||
|
case 0x8f: /* JNLE */
|
||||||
|
JumpSIw((get_SF() == get_OF()) && !get_ZF());break;
|
||||||
|
case 0xa0: /* PUSH FS */
|
||||||
|
Push_16(Segs[fs].value);break;
|
||||||
|
case 0xa1: /* POP FS */
|
||||||
|
SetSegment_16(fs,Pop_16());break;
|
||||||
|
case 0xa4: /* SHLD Ew,Gw,Ib */
|
||||||
|
{
|
||||||
|
GetRMrw;
|
||||||
|
if (rm >= 0xc0 ) {GetEArw;DSHLW(*earw,*rmrw,Fetchb(),LoadRw,SaveRw);}
|
||||||
|
else {GetEAa;DSHLW(eaa,*rmrw,Fetchb(),LoadMw,SaveMw);}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0xa5: /* SHLD Ew,Gw,CL */
|
||||||
|
{
|
||||||
|
GetRMrw;
|
||||||
|
if (rm >= 0xc0 ) {GetEArw;DSHLW(*earw,*rmrw,reg_cl,LoadRw,SaveRw);}
|
||||||
|
else {GetEAa;DSHLW(eaa,*rmrw,reg_cl,LoadMw,SaveMw);}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0xa8: /* PUSH GS */
|
||||||
|
Push_16(Segs[gs].value);break;
|
||||||
|
case 0xa9: /* POP GS */
|
||||||
|
SetSegment_16(gs,Pop_16());break;
|
||||||
|
case 0xac: /* SHRD Ew,Gw,Ib */
|
||||||
|
{
|
||||||
|
GetRMrw;
|
||||||
|
if (rm >= 0xc0 ) {GetEArw;DSHRW(*earw,*rmrw,Fetchb(),LoadRw,SaveRw);}
|
||||||
|
else {GetEAa;DSHRW(eaa,*rmrw,Fetchb(),LoadMw,SaveMw);}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0xad: /* SHRD Ew,Gw,CL */
|
||||||
|
{
|
||||||
|
GetRMrw;
|
||||||
|
if (rm >= 0xc0 ) {GetEArw;DSHRW(*earw,*rmrw,reg_cl,LoadRw,SaveRw);}
|
||||||
|
else {GetEAa;DSHRW(eaa,*rmrw,reg_cl,LoadMw,SaveMw);}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0xaf: /* IMUL Gw,Ew */
|
||||||
|
{
|
||||||
|
GetRMrw;
|
||||||
|
Bit32s res;
|
||||||
|
if (rm >= 0xc0 ) {GetEArw;res=(Bit32s)(*rmrw) * (Bit32s)(*earws);}
|
||||||
|
else {GetEAa;res=(Bit32s)(*rmrw) *(Bit32s)LoadMws(eaa);}
|
||||||
|
*rmrw=res & 0xFFFF;
|
||||||
|
flags.type=t_MUL;
|
||||||
|
if ((res> -32768) && (res<32767)) {flags.cf=false;flags.of=false;}
|
||||||
|
else {flags.cf=true;flags.of=true;}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0xb4: /* LFS */
|
||||||
|
{
|
||||||
|
GetRMrw;GetEAa;
|
||||||
|
*rmrw=LoadMw(eaa);SetSegment_16(fs,LoadMw(eaa+2));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0xb5: /* LGS */
|
||||||
|
{
|
||||||
|
GetRMrw;GetEAa;
|
||||||
|
*rmrw=LoadMw(eaa);SetSegment_16(gs,LoadMw(eaa+2));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0xb6: /* MOVZX Gw,Eb */
|
||||||
|
{
|
||||||
|
GetRMrw;
|
||||||
|
if (rm >= 0xc0 ) {GetEArb;*rmrw=*earb;}
|
||||||
|
else {GetEAa;*rmrw=LoadMb(eaa);}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0xba: /* GRP8 Ew,Ib */
|
||||||
|
{
|
||||||
|
GetRM;
|
||||||
|
if (rm >= 0xc0 ) {
|
||||||
|
GetEArw;
|
||||||
|
Bit16u mask=1 << (Fetchb() & 15);
|
||||||
|
flags.cf=(*earw & mask)>0;
|
||||||
|
switch (rm & 0x38) {
|
||||||
|
case 0x20: /* BT */
|
||||||
|
break;
|
||||||
|
case 0x28: /* BTS */
|
||||||
|
*earw|=mask;
|
||||||
|
break;
|
||||||
|
case 0x30: /* BTR */
|
||||||
|
*earw&=~mask;
|
||||||
|
break;
|
||||||
|
case 0x38: /* BTC */
|
||||||
|
if (flags.cf) *earw&=~mask;
|
||||||
|
else *earw|=mask;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
GetEAa;Bit16u old=LoadMw(eaa);
|
||||||
|
Bit16u mask=1 << (Fetchb() & 15);
|
||||||
|
flags.cf=(old & mask)>0;
|
||||||
|
switch (rm & 0x38) {
|
||||||
|
case 0x20: /* BT */
|
||||||
|
break;
|
||||||
|
case 0x28: /* BTS */
|
||||||
|
SaveMw(eaa,old|mask);
|
||||||
|
break;
|
||||||
|
case 0x30: /* BTR */
|
||||||
|
SaveMw(eaa,old & ~mask);
|
||||||
|
break;
|
||||||
|
case 0x38: /* BTC */
|
||||||
|
if (flags.cf) old&=~mask;
|
||||||
|
else old|=mask;
|
||||||
|
SaveMw(eaa,old);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (flags.type!=t_CF) flags.prev_type=flags.type;
|
||||||
|
flags.type=t_CF;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 0xbe: /* MOVSX Gw,Eb */
|
||||||
|
{
|
||||||
|
GetRMrw;
|
||||||
|
if (rm >= 0xc0 ) {GetEArb;*rmrw=*earbs;}
|
||||||
|
else {GetEAa;*rmrw=LoadMbs(eaa);}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
SUBIP(1);
|
||||||
|
E_Exit("CPU:Opcode 0F:%2X Unhandled",Fetchb());
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2008 The DOSBox Team
|
* Copyright (C) 2002 The DOSBox Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -9,23 +9,12 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Library General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: risc_armv4le.h,v 1.2 2008/09/02 20:44:41 c2woody Exp $ */
|
/* Setup the CS:IP and SS:SP Pointers */
|
||||||
|
LOADIP;
|
||||||
|
|
||||||
/* ARMv4 (little endian) backend (switcher) by M-HT */
|
|
||||||
|
|
||||||
#include "risc_armv4le-common.h"
|
|
||||||
|
|
||||||
// choose your destiny:
|
|
||||||
#include "risc_armv4le-thumb-niw.h"
|
|
||||||
//#include "risc_armv4le-thumb-iw.h"
|
|
||||||
//#include "risc_armv4le-thumb.h"
|
|
||||||
//#include "risc_armv4le-s3.h"
|
|
||||||
//#include "risc_armv4le-o3.h"
|
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2002-2007 The DOSBox Team
|
* Copyright (C) 2002 The DOSBox Team
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -9,26 +9,11 @@
|
|||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU Library General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __XMS_H__
|
SAVEIP;
|
||||||
#define __XMS_H__
|
|
||||||
|
|
||||||
Bitu XMS_QueryFreeMemory (Bit16u& largestFree, Bit16u& totalFree);
|
|
||||||
Bitu XMS_AllocateMemory (Bitu size, Bit16u& handle);
|
|
||||||
Bitu XMS_FreeMemory (Bitu handle);
|
|
||||||
Bitu XMS_MoveMemory (PhysPt bpt);
|
|
||||||
Bitu XMS_LockMemory (Bitu handle, Bit32u& address);
|
|
||||||
Bitu XMS_UnlockMemory (Bitu handle);
|
|
||||||
Bitu XMS_GetHandleInformation(Bitu handle, Bit8u& lockCount, Bit8u& numFree, Bit16u& size);
|
|
||||||
Bitu XMS_ResizeMemory (Bitu handle, Bitu newSize);
|
|
||||||
|
|
||||||
Bitu XMS_EnableA20 (bool enable);
|
|
||||||
Bitu XMS_GetEnabledA20 (void);
|
|
||||||
|
|
||||||
#endif
|
|
191
src/cpu/core_16/support.h
Normal file
191
src/cpu/core_16/support.h
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
EAPoint IPPoint;
|
||||||
|
|
||||||
|
|
||||||
|
#define SUBIP(a) IPPoint-=a
|
||||||
|
#define SETIP(a) IPPoint=SegBase(cs)+a
|
||||||
|
#define GETIP (Bit16u)(IPPoint-SegBase(cs))
|
||||||
|
#define SAVEIP reg_ip=GETIP
|
||||||
|
#define LOADIP IPPoint=SegBase(cs)+reg_ip
|
||||||
|
/*
|
||||||
|
#define ADDIP(a) { \
|
||||||
|
Bit16u add_ip=(Bit16u)(IPPoint-SegBase(cs)); \
|
||||||
|
add_ip+=a; \
|
||||||
|
IPPoint=SegBase(cs)+add_ip; \
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
static INLINE void ADDIP(Bit16u add) {
|
||||||
|
|
||||||
|
// Bit16u oldip=(IPPoint-SegBase(cs));
|
||||||
|
// oldip+=add;
|
||||||
|
// IPPoint=SegBase(cs)+oldip;
|
||||||
|
IPPoint=SegBase(cs)+((Bit16u)(((Bit16u)(IPPoint-SegBase(cs)))+(Bit16u)add));
|
||||||
|
}
|
||||||
|
|
||||||
|
static INLINE void ADDIPFAST(Bit16s blah) {
|
||||||
|
IPPoint+=blah;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ERRORRETURN(a) { error_ret=a;goto errorreturn; }
|
||||||
|
|
||||||
|
|
||||||
|
static INLINE Bit8u Fetchb() {
|
||||||
|
Bit8u temp=LoadMb(IPPoint);
|
||||||
|
IPPoint+=1;
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static INLINE Bit16u Fetchw() {
|
||||||
|
Bit16u temp=LoadMw(IPPoint);
|
||||||
|
IPPoint+=2;
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
static INLINE Bit32u Fetchd() {
|
||||||
|
Bit32u temp=LoadMd(IPPoint);
|
||||||
|
IPPoint+=4;
|
||||||
|
return temp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static INLINE Bit8s Fetchbs() {
|
||||||
|
return Fetchb();
|
||||||
|
}
|
||||||
|
static INLINE Bit16s Fetchws() {
|
||||||
|
return Fetchw();
|
||||||
|
}
|
||||||
|
|
||||||
|
static INLINE Bit32s Fetchds() {
|
||||||
|
return Fetchd();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static INLINE void Push_16(Bit16u blah) {
|
||||||
|
reg_sp-=2;
|
||||||
|
SaveMw(SegBase(ss)+reg_sp,blah);
|
||||||
|
};
|
||||||
|
|
||||||
|
static INLINE void Push_32(Bit32u blah) {
|
||||||
|
reg_sp-=4;
|
||||||
|
SaveMd(SegBase(ss)+reg_sp,blah);
|
||||||
|
};
|
||||||
|
|
||||||
|
static INLINE Bit16u Pop_16() {
|
||||||
|
Bit16u temp=LoadMw(SegBase(ss)+reg_sp);
|
||||||
|
reg_sp+=2;
|
||||||
|
return temp;
|
||||||
|
};
|
||||||
|
|
||||||
|
static INLINE Bit32u Pop_32() {
|
||||||
|
Bit32u temp=LoadMd(SegBase(ss)+reg_sp);
|
||||||
|
reg_sp+=4;
|
||||||
|
return temp;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define stringDI \
|
||||||
|
EAPoint to; \
|
||||||
|
to=SegBase(es)+reg_di
|
||||||
|
|
||||||
|
#define stringSI \
|
||||||
|
EAPoint from; \
|
||||||
|
if (segprefix_on) { \
|
||||||
|
from=(segprefix_base+reg_si); \
|
||||||
|
SegPrefixReset; \
|
||||||
|
} else { \
|
||||||
|
from=SegBase(ds)+reg_si; \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#include "helpers.h"
|
||||||
|
#include "table_ea.h"
|
||||||
|
#include "../modrm.h"
|
||||||
|
#include "instructions.h"
|
||||||
|
|
||||||
|
|
||||||
|
static INLINE void Rep_66(Bit16s direct,EAPoint from,EAPoint to) {
|
||||||
|
bool again;
|
||||||
|
do {
|
||||||
|
again=false;
|
||||||
|
Bit8u repcode=Fetchb();
|
||||||
|
switch (repcode) {
|
||||||
|
case 0x26: /* ES Prefix */
|
||||||
|
again=true;
|
||||||
|
from=SegBase(es);
|
||||||
|
break;
|
||||||
|
case 0x2e: /* CS Prefix */
|
||||||
|
again=true;
|
||||||
|
from=SegBase(cs);
|
||||||
|
break;
|
||||||
|
case 0x36: /* SS Prefix */
|
||||||
|
again=true;
|
||||||
|
from=SegBase(ss);
|
||||||
|
break;
|
||||||
|
case 0x3e: /* DS Prefix */
|
||||||
|
again=true;
|
||||||
|
from=SegBase(ds);
|
||||||
|
break;
|
||||||
|
case 0xa5: /* REP MOVSD */
|
||||||
|
for (;reg_cx>0;reg_cx--) {
|
||||||
|
SaveMd(to+reg_di,LoadMd(from+reg_si));
|
||||||
|
reg_di+=direct*4;
|
||||||
|
reg_si+=direct*4;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0xab: /* REP STOSW */
|
||||||
|
for (;reg_cx>0;reg_cx--) {
|
||||||
|
SaveMd(to+reg_di,reg_eax);
|
||||||
|
reg_di+=direct*4;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
E_Exit("CPU:Opcode 66:Illegal REP prefix %2X",repcode);
|
||||||
|
}
|
||||||
|
} while (again);
|
||||||
|
}
|
||||||
|
|
||||||
|
//flags.io and nt shouldn't be compiled for 386
|
||||||
|
#define Save_Flagsw(FLAGW) \
|
||||||
|
{ \
|
||||||
|
flags.type=t_UNKNOWN; \
|
||||||
|
flags.cf =(FLAGW & 0x001)>0;flags.pf =(FLAGW & 0x004)>0; \
|
||||||
|
flags.af =(FLAGW & 0x010)>0;flags.zf =(FLAGW & 0x040)>0; \
|
||||||
|
flags.sf =(FLAGW & 0x080)>0;flags.tf =(FLAGW & 0x100)>0; \
|
||||||
|
flags.intf =(FLAGW & 0x200)>0; \
|
||||||
|
flags.df =(FLAGW & 0x400)>0;flags.of =(FLAGW & 0x800)>0; \
|
||||||
|
flags.io =(FLAGW >> 12) & 0x03; \
|
||||||
|
flags.nt =(FLAGW & 0x4000)>0; \
|
||||||
|
if (flags.intf && PIC_IRQCheck) { \
|
||||||
|
SAVEIP; \
|
||||||
|
PIC_runIRQs(); \
|
||||||
|
LOADIP; \
|
||||||
|
} \
|
||||||
|
if (flags.tf) E_Exit("CPU:Trap Flag not supported"); \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// if (flags.tf) { \
|
||||||
|
// cpudecoder=CPU_Real_16_Slow_Decode_Special; \
|
||||||
|
// return CBRET_NONE; \
|
||||||
|
// } \
|
283
src/cpu/core_16/table_ea.h
Normal file
283
src/cpu/core_16/table_ea.h
Normal file
@ -0,0 +1,283 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2002 The DOSBox Team
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Some variables for EA Loolkup */
|
||||||
|
|
||||||
|
typedef EAPoint (*GetEATable[256])(void);
|
||||||
|
static GetEATable * lookupEATable;
|
||||||
|
|
||||||
|
static EAPoint segprefix_base;
|
||||||
|
static bool segprefix_on=false;
|
||||||
|
|
||||||
|
#define SegPrefix(blah) \
|
||||||
|
segprefix_base=SegBase(blah); \
|
||||||
|
segprefix_on=true; \
|
||||||
|
lookupEATable=&GetEA_16_s; \
|
||||||
|
goto restart; \
|
||||||
|
|
||||||
|
#define SegPrefix_66(blah) \
|
||||||
|
segprefix_base=SegBase(blah); \
|
||||||
|
segprefix_on=true; \
|
||||||
|
lookupEATable=&GetEA_16_s; \
|
||||||
|
goto restart_66; \
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define SegPrefixReset \
|
||||||
|
segprefix_on=false;lookupEATable=&GetEA_16_n;
|
||||||
|
|
||||||
|
|
||||||
|
/* The MOD/RM Decoder for EA for this decoder's addressing modes */
|
||||||
|
static EAPoint EA_16_00_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_si); }
|
||||||
|
static EAPoint EA_16_01_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_di); }
|
||||||
|
static EAPoint EA_16_02_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_si); }
|
||||||
|
static EAPoint EA_16_03_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_di); }
|
||||||
|
static EAPoint EA_16_04_n(void) { return SegBase(ds)+(Bit16u)(reg_si); }
|
||||||
|
static EAPoint EA_16_05_n(void) { return SegBase(ds)+(Bit16u)(reg_di); }
|
||||||
|
static EAPoint EA_16_06_n(void) { return SegBase(ds)+(Bit16u)(Fetchw());}
|
||||||
|
static EAPoint EA_16_07_n(void) { return SegBase(ds)+(Bit16u)(reg_bx); }
|
||||||
|
|
||||||
|
static EAPoint EA_16_40_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchbs()); }
|
||||||
|
static EAPoint EA_16_41_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchbs()); }
|
||||||
|
static EAPoint EA_16_42_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchbs()); }
|
||||||
|
static EAPoint EA_16_43_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchbs()); }
|
||||||
|
static EAPoint EA_16_44_n(void) { return SegBase(ds)+(Bit16u)(reg_si+Fetchbs()); }
|
||||||
|
static EAPoint EA_16_45_n(void) { return SegBase(ds)+(Bit16u)(reg_di+Fetchbs()); }
|
||||||
|
static EAPoint EA_16_46_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+Fetchbs()); }
|
||||||
|
static EAPoint EA_16_47_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+Fetchbs()); }
|
||||||
|
|
||||||
|
static EAPoint EA_16_80_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_si+Fetchws()); }
|
||||||
|
static EAPoint EA_16_81_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+(Bit16s)reg_di+Fetchws()); }
|
||||||
|
static EAPoint EA_16_82_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_si+Fetchws()); }
|
||||||
|
static EAPoint EA_16_83_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+(Bit16s)reg_di+Fetchws()); }
|
||||||
|
static EAPoint EA_16_84_n(void) { return SegBase(ds)+(Bit16u)(reg_si+Fetchws()); }
|
||||||
|
static EAPoint EA_16_85_n(void) { return SegBase(ds)+(Bit16u)(reg_di+Fetchws()); }
|
||||||
|
static EAPoint EA_16_86_n(void) { return SegBase(ss)+(Bit16u)(reg_bp+Fetchws()); }
|
||||||
|
static EAPoint EA_16_87_n(void) { return SegBase(ds)+(Bit16u)(reg_bx+Fetchws()); }
|
||||||
|
|
||||||
|
static GetEATable GetEA_16_n={
|
||||||
|
/* 00 */
|
||||||
|
EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
|
||||||
|
EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
|
||||||
|
EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
|
||||||
|
EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
|
||||||
|
EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
|
||||||
|
EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
|
||||||
|
EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
|
||||||
|
EA_16_00_n,EA_16_01_n,EA_16_02_n,EA_16_03_n,EA_16_04_n,EA_16_05_n,EA_16_06_n,EA_16_07_n,
|
||||||
|
/* 01 */
|
||||||
|
EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
|
||||||
|
EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
|
||||||
|
EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
|
||||||
|
EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
|
||||||
|
EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
|
||||||
|
EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
|
||||||
|
EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
|
||||||
|
EA_16_40_n,EA_16_41_n,EA_16_42_n,EA_16_43_n,EA_16_44_n,EA_16_45_n,EA_16_46_n,EA_16_47_n,
|
||||||
|
/* 10 */
|
||||||
|
EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
|
||||||
|
EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
|
||||||
|
EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
|
||||||
|
EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
|
||||||
|
EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
|
||||||
|
EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
|
||||||
|
EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
|
||||||
|
EA_16_80_n,EA_16_81_n,EA_16_82_n,EA_16_83_n,EA_16_84_n,EA_16_85_n,EA_16_86_n,EA_16_87_n,
|
||||||
|
/* 11 These are illegal so make em 0 */
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define prefixed(val) EAPoint ret=segprefix_base+val;SegPrefixReset;return ret;
|
||||||
|
|
||||||
|
static EAPoint EA_16_00_s(void) { prefixed((Bit16u)(reg_bx+(Bit16s)reg_si)) }
|
||||||
|
static EAPoint EA_16_01_s(void) { prefixed((Bit16u)(reg_bx+(Bit16s)reg_di)) }
|
||||||
|
static EAPoint EA_16_02_s(void) { prefixed((Bit16u)(reg_bp+(Bit16s)reg_si)) }
|
||||||
|
static EAPoint EA_16_03_s(void) { prefixed((Bit16u)(reg_bp+(Bit16s)reg_di)) }
|
||||||
|
static EAPoint EA_16_04_s(void) { prefixed((Bit16u)(reg_si)) }
|
||||||
|
static EAPoint EA_16_05_s(void) { prefixed((Bit16u)(reg_di)) }
|
||||||
|
static EAPoint EA_16_06_s(void) { prefixed((Bit16u)(Fetchw())) }
|
||||||
|
static EAPoint EA_16_07_s(void) { prefixed((Bit16u)(reg_bx)) }
|
||||||
|
|
||||||
|
static EAPoint EA_16_40_s(void) { prefixed((Bit16u)(reg_bx+(Bit16s)reg_si+Fetchbs())) }
|
||||||
|
static EAPoint EA_16_41_s(void) { prefixed((Bit16u)(reg_bx+(Bit16s)reg_di+Fetchbs())) }
|
||||||
|
static EAPoint EA_16_42_s(void) { prefixed((Bit16u)(reg_bp+(Bit16s)reg_si+Fetchbs())) }
|
||||||
|
static EAPoint EA_16_43_s(void) { prefixed((Bit16u)(reg_bp+(Bit16s)reg_di+Fetchbs())) }
|
||||||
|
static EAPoint EA_16_44_s(void) { prefixed((Bit16u)(reg_si+Fetchbs())) }
|
||||||
|
static EAPoint EA_16_45_s(void) { prefixed((Bit16u)(reg_di+Fetchbs())) }
|
||||||
|
static EAPoint EA_16_46_s(void) { prefixed((Bit16u)(reg_bp+Fetchbs())) }
|
||||||
|
static EAPoint EA_16_47_s(void) { prefixed((Bit16u)(reg_bx+Fetchbs())) }
|
||||||
|
|
||||||
|
static EAPoint EA_16_80_s(void) { prefixed((Bit16u)(reg_bx+(Bit16s)reg_si+Fetchws())) }
|
||||||
|
static EAPoint EA_16_81_s(void) { prefixed((Bit16u)(reg_bx+(Bit16s)reg_di+Fetchws())) }
|
||||||
|
static EAPoint EA_16_82_s(void) { prefixed((Bit16u)(reg_bp+(Bit16s)reg_si+Fetchws())) }
|
||||||
|
static EAPoint EA_16_83_s(void) { prefixed((Bit16u)(reg_bp+(Bit16s)reg_di+Fetchws())) }
|
||||||
|
static EAPoint EA_16_84_s(void) { prefixed((Bit16u)(reg_si+Fetchws())) }
|
||||||
|
static EAPoint EA_16_85_s(void) { prefixed((Bit16u)(reg_di+Fetchws())) }
|
||||||
|
static EAPoint EA_16_86_s(void) { prefixed((Bit16u)(reg_bp+Fetchws())) }
|
||||||
|
static EAPoint EA_16_87_s(void) { prefixed((Bit16u)(reg_bx+Fetchws())) }
|
||||||
|
|
||||||
|
static GetEATable GetEA_16_s={
|
||||||
|
/* 00 */
|
||||||
|
EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s,
|
||||||
|
EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s,
|
||||||
|
EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s,
|
||||||
|
EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s,
|
||||||
|
EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s,
|
||||||
|
EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s,
|
||||||
|
EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s,
|
||||||
|
EA_16_00_s,EA_16_01_s,EA_16_02_s,EA_16_03_s,EA_16_04_s,EA_16_05_s,EA_16_06_s,EA_16_07_s,
|
||||||
|
/* 01 */
|
||||||
|
EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s,
|
||||||
|
EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s,
|
||||||
|
EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s,
|
||||||
|
EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s,
|
||||||
|
EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s,
|
||||||
|
EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s,
|
||||||
|
EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s,
|
||||||
|
EA_16_40_s,EA_16_41_s,EA_16_42_s,EA_16_43_s,EA_16_44_s,EA_16_45_s,EA_16_46_s,EA_16_47_s,
|
||||||
|
/* 10 */
|
||||||
|
EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s,
|
||||||
|
EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s,
|
||||||
|
EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s,
|
||||||
|
EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s,
|
||||||
|
EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s,
|
||||||
|
EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s,
|
||||||
|
EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s,
|
||||||
|
EA_16_80_s,EA_16_81_s,EA_16_82_s,EA_16_83_s,EA_16_84_s,EA_16_85_s,EA_16_86_s,EA_16_87_s,
|
||||||
|
/* 11 These are illegal so make em 0 */
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
INLINE EAPoint Sib(Bitu mode) {
|
||||||
|
Bit8u sib=Fetchb();
|
||||||
|
EAPoint base;
|
||||||
|
switch (sib&7) {
|
||||||
|
case 0: /* EAX Base */
|
||||||
|
base=SegBase(ds)+reg_eax;break;
|
||||||
|
case 1: /* ECX Base */
|
||||||
|
base=SegBase(ds)+reg_ecx;break;
|
||||||
|
case 2: /* EDX Base */
|
||||||
|
base=SegBase(ds)+reg_edx;break;
|
||||||
|
case 3: /* EBX Base */
|
||||||
|
base=SegBase(ds)+reg_ebx;break;
|
||||||
|
case 4: /* ESP Base */
|
||||||
|
base=SegBase(ds)+reg_esp;break;
|
||||||
|
case 5: /* #1 Base */
|
||||||
|
if (!mode) {
|
||||||
|
base=SegBase(ds)+Fetchd();break;
|
||||||
|
} else {
|
||||||
|
base=SegBase(ss)+reg_ebp;break;
|
||||||
|
}
|
||||||
|
case 6: /* ESI Base */
|
||||||
|
base=SegBase(ds)+reg_esi;break;
|
||||||
|
case 7: /* EDI Base */
|
||||||
|
base=SegBase(ds)+reg_edi;break;
|
||||||
|
}
|
||||||
|
Bitu shift=sib >> 6;
|
||||||
|
switch ((sib >>3) &7) {
|
||||||
|
case 0: /* EAX Index */
|
||||||
|
base+=(Bit32s)reg_eax<<shift;break;
|
||||||
|
case 1: /* ECX Index */
|
||||||
|
base+=(Bit32s)reg_ecx<<shift;break;
|
||||||
|
case 2: /* EDX Index */
|
||||||
|
base+=(Bit32s)reg_edx<<shift;break;
|
||||||
|
case 3: /* EBX Index */
|
||||||
|
base+=(Bit32s)reg_ebx<<shift;break;
|
||||||
|
case 4: /* None */
|
||||||
|
break;
|
||||||
|
case 5: /* EBP Index */
|
||||||
|
base+=(Bit32s)reg_ebp<<shift;break;
|
||||||
|
case 6: /* ESI Index */
|
||||||
|
base+=(Bit32s)reg_esi<<shift;break;
|
||||||
|
case 7: /* EDI Index */
|
||||||
|
base+=(Bit32s)reg_edi<<shift;break;
|
||||||
|
};
|
||||||
|
return base;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static EAPoint EA_32_00_n(void) { return SegBase(ds)+reg_eax; }
|
||||||
|
static EAPoint EA_32_01_n(void) { return SegBase(ds)+reg_ecx; }
|
||||||
|
static EAPoint EA_32_02_n(void) { return SegBase(ds)+reg_edx; }
|
||||||
|
static EAPoint EA_32_03_n(void) { return SegBase(ds)+reg_ebx; }
|
||||||
|
static EAPoint EA_32_04_n(void) { return Sib(0);}
|
||||||
|
static EAPoint EA_32_05_n(void) { return SegBase(ds)+Fetchd(); }
|
||||||
|
static EAPoint EA_32_06_n(void) { return SegBase(ss)+reg_esi; }
|
||||||
|
static EAPoint EA_32_07_n(void) { return SegBase(ds)+reg_edi; }
|
||||||
|
|
||||||
|
static EAPoint EA_32_40_n(void) { return SegBase(ds)+reg_eax+Fetchbs(); }
|
||||||
|
static EAPoint EA_32_41_n(void) { return SegBase(ds)+reg_ecx+Fetchbs(); }
|
||||||
|
static EAPoint EA_32_42_n(void) { return SegBase(ds)+reg_edx+Fetchbs(); }
|
||||||
|
static EAPoint EA_32_43_n(void) { return SegBase(ds)+reg_ebx+Fetchbs(); }
|
||||||
|
static EAPoint EA_32_44_n(void) { return Sib(1)+Fetchbs();}
|
||||||
|
static EAPoint EA_32_45_n(void) { return SegBase(ss)+reg_ebp+Fetchbs(); }
|
||||||
|
static EAPoint EA_32_46_n(void) { return SegBase(ds)+reg_esi+Fetchbs(); }
|
||||||
|
static EAPoint EA_32_47_n(void) { return SegBase(ds)+reg_edi+Fetchbs(); }
|
||||||
|
|
||||||
|
static EAPoint EA_32_80_n(void) { return SegBase(ds)+reg_eax+Fetchds(); }
|
||||||
|
static EAPoint EA_32_81_n(void) { return SegBase(ds)+reg_ecx+Fetchds(); }
|
||||||
|
static EAPoint EA_32_82_n(void) { return SegBase(ds)+reg_edx+Fetchds(); }
|
||||||
|
static EAPoint EA_32_83_n(void) { return SegBase(ds)+reg_ebx+Fetchds(); }
|
||||||
|
static EAPoint EA_32_84_n(void) { return Sib(2)+Fetchds();}
|
||||||
|
static EAPoint EA_32_85_n(void) { return SegBase(ss)+reg_ebp+Fetchds(); }
|
||||||
|
static EAPoint EA_32_86_n(void) { return SegBase(ds)+reg_esi+Fetchds(); }
|
||||||
|
static EAPoint EA_32_87_n(void) { return SegBase(ds)+reg_edi+Fetchds(); }
|
||||||
|
|
||||||
|
static GetEATable GetEA_32_n={
|
||||||
|
/* 00 */
|
||||||
|
EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
|
||||||
|
EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
|
||||||
|
EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
|
||||||
|
EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
|
||||||
|
EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
|
||||||
|
EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
|
||||||
|
EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
|
||||||
|
EA_32_00_n,EA_32_01_n,EA_32_02_n,EA_32_03_n,EA_32_04_n,EA_32_05_n,EA_32_06_n,EA_32_07_n,
|
||||||
|
/* 01 */
|
||||||
|
EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
|
||||||
|
EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
|
||||||
|
EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
|
||||||
|
EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
|
||||||
|
EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
|
||||||
|
EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
|
||||||
|
EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
|
||||||
|
EA_32_40_n,EA_32_41_n,EA_32_42_n,EA_32_43_n,EA_32_44_n,EA_32_45_n,EA_32_46_n,EA_32_47_n,
|
||||||
|
/* 10 */
|
||||||
|
EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
|
||||||
|
EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
|
||||||
|
EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
|
||||||
|
EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
|
||||||
|
EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
|
||||||
|
EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
|
||||||
|
EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
|
||||||
|
EA_32_80_n,EA_32_81_n,EA_32_82_n,EA_32_83_n,EA_32_84_n,EA_32_85_n,EA_32_86_n,EA_32_87_n,
|
||||||
|
/* 11 These are illegal so make em 0 */
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
};
|
||||||
|
|
@ -1,476 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2002-2007 The DOSBox Team
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* $Id: core_dyn_x86.cpp,v 1.34 2007/11/24 17:26:48 c2woody Exp $ */
|
|
||||||
|
|
||||||
#include "dosbox.h"
|
|
||||||
|
|
||||||
#if (C_DYNAMIC_X86)
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#if defined (WIN32)
|
|
||||||
#include <windows.h>
|
|
||||||
#include <winbase.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (C_HAVE_MPROTECT)
|
|
||||||
#include <sys/mman.h>
|
|
||||||
|
|
||||||
#include <limits.h>
|
|
||||||
#ifndef PAGESIZE
|
|
||||||
#define PAGESIZE 4096
|
|
||||||
#endif
|
|
||||||
#endif /* C_HAVE_MPROTECT */
|
|
||||||
|
|
||||||
#include "callback.h"
|
|
||||||
#include "regs.h"
|
|
||||||
#include "mem.h"
|
|
||||||
#include "cpu.h"
|
|
||||||
#include "debug.h"
|
|
||||||
#include "paging.h"
|
|
||||||
#include "inout.h"
|
|
||||||
#include "fpu.h"
|
|
||||||
|
|
||||||
#define CACHE_MAXSIZE (4096*3)
|
|
||||||
#define CACHE_TOTAL (1024*1024*8)
|
|
||||||
#define CACHE_PAGES (512)
|
|
||||||
#define CACHE_BLOCKS (64*1024)
|
|
||||||
#define CACHE_ALIGN (16)
|
|
||||||
#define DYN_HASH_SHIFT (4)
|
|
||||||
#define DYN_PAGE_HASH (4096>>DYN_HASH_SHIFT)
|
|
||||||
#define DYN_LINKS (16)
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
#define DYN_LOG LOG_MSG
|
|
||||||
#else
|
|
||||||
#define DYN_LOG
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if C_FPU
|
|
||||||
#define CPU_FPU 1 //Enable FPU escape instructions
|
|
||||||
#endif
|
|
||||||
|
|
||||||
enum {
|
|
||||||
G_EAX,G_ECX,G_EDX,G_EBX,
|
|
||||||
G_ESP,G_EBP,G_ESI,G_EDI,
|
|
||||||
G_ES,G_CS,G_SS,G_DS,G_FS,G_GS,
|
|
||||||
G_FLAGS,G_NEWESP,G_EIP,
|
|
||||||
G_EA,G_STACK,G_CYCLES,
|
|
||||||
G_TMPB,G_TMPW,G_SHIFT,
|
|
||||||
G_EXIT,
|
|
||||||
G_MAX,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum SingleOps {
|
|
||||||
SOP_INC,SOP_DEC,
|
|
||||||
SOP_NOT,SOP_NEG,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum DualOps {
|
|
||||||
DOP_ADD,DOP_ADC,
|
|
||||||
DOP_SUB,DOP_SBB,
|
|
||||||
DOP_CMP,DOP_XOR,
|
|
||||||
DOP_AND,DOP_OR,
|
|
||||||
DOP_TEST,
|
|
||||||
DOP_MOV,
|
|
||||||
DOP_XCHG,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum ShiftOps {
|
|
||||||
SHIFT_ROL,SHIFT_ROR,
|
|
||||||
SHIFT_RCL,SHIFT_RCR,
|
|
||||||
SHIFT_SHL,SHIFT_SHR,
|
|
||||||
SHIFT_SAL,SHIFT_SAR,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum BranchTypes {
|
|
||||||
BR_O,BR_NO,BR_B,BR_NB,
|
|
||||||
BR_Z,BR_NZ,BR_BE,BR_NBE,
|
|
||||||
BR_S,BR_NS,BR_P,BR_NP,
|
|
||||||
BR_L,BR_NL,BR_LE,BR_NLE
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
enum BlockReturn {
|
|
||||||
BR_Normal=0,
|
|
||||||
BR_Cycles,
|
|
||||||
BR_Link1,BR_Link2,
|
|
||||||
BR_Opcode,
|
|
||||||
#if (C_DEBUG)
|
|
||||||
BR_OpcodeFull,
|
|
||||||
#endif
|
|
||||||
BR_Iret,
|
|
||||||
BR_CallBack,
|
|
||||||
BR_SMCBlock
|
|
||||||
};
|
|
||||||
|
|
||||||
#define SMC_CURRENT_BLOCK 0xffff
|
|
||||||
|
|
||||||
|
|
||||||
#define DYNFLG_HAS16 0x1 //Would like 8-bit host reg support
|
|
||||||
#define DYNFLG_HAS8 0x2 //Would like 16-bit host reg support
|
|
||||||
#define DYNFLG_LOAD 0x4 //Load value when accessed
|
|
||||||
#define DYNFLG_SAVE 0x8 //Needs to be saved back at the end of block
|
|
||||||
#define DYNFLG_CHANGED 0x10 //Value is in a register and changed from load
|
|
||||||
#define DYNFLG_ACTIVE 0x20 //Register has an active value
|
|
||||||
|
|
||||||
class GenReg;
|
|
||||||
class CodePageHandler;
|
|
||||||
|
|
||||||
struct DynReg {
|
|
||||||
Bitu flags;
|
|
||||||
GenReg * genreg;
|
|
||||||
void * data;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum DynAccess {
|
|
||||||
DA_d,DA_w,
|
|
||||||
DA_bh,DA_bl
|
|
||||||
};
|
|
||||||
|
|
||||||
enum ByteCombo {
|
|
||||||
BC_ll,BC_lh,
|
|
||||||
BC_hl,BC_hh,
|
|
||||||
};
|
|
||||||
|
|
||||||
static DynReg DynRegs[G_MAX];
|
|
||||||
#define DREG(_WHICH_) &DynRegs[G_ ## _WHICH_ ]
|
|
||||||
|
|
||||||
static struct {
|
|
||||||
Bitu ea,tmpb,tmpd,stack,shift,newesp;
|
|
||||||
} extra_regs;
|
|
||||||
|
|
||||||
static void IllegalOption(const char* msg) {
|
|
||||||
E_Exit("DynCore: illegal option in %s",msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "core_dyn_x86/cache.h"
|
|
||||||
|
|
||||||
static struct {
|
|
||||||
Bitu callback;
|
|
||||||
Bit32u readdata;
|
|
||||||
} core_dyn;
|
|
||||||
|
|
||||||
static struct {
|
|
||||||
Bit32u state[32];
|
|
||||||
FPU_P_Reg temp,temp2;
|
|
||||||
Bit32u dh_fpu_enabled;
|
|
||||||
Bit32u state_used;
|
|
||||||
Bit32u cw,host_cw;
|
|
||||||
Bit8u temp_state[128];
|
|
||||||
} dyn_dh_fpu;
|
|
||||||
|
|
||||||
|
|
||||||
#include "core_dyn_x86/risc_x86.h"
|
|
||||||
|
|
||||||
struct DynState {
|
|
||||||
DynReg regs[G_MAX];
|
|
||||||
};
|
|
||||||
|
|
||||||
static void dyn_flags_host_to_gen(void) {
|
|
||||||
gen_dop_word(DOP_MOV,true,DREG(EXIT),DREG(FLAGS));
|
|
||||||
gen_dop_word_imm(DOP_AND,true,DREG(EXIT),FMASK_TEST);
|
|
||||||
gen_load_flags(DREG(EXIT));
|
|
||||||
gen_releasereg(DREG(EXIT));
|
|
||||||
gen_releasereg(DREG(FLAGS));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dyn_flags_gen_to_host(void) {
|
|
||||||
gen_save_flags(DREG(EXIT));
|
|
||||||
gen_dop_word_imm(DOP_AND,true,DREG(EXIT),FMASK_TEST);
|
|
||||||
gen_dop_word_imm(DOP_AND,true,DREG(FLAGS),~FMASK_TEST);
|
|
||||||
gen_dop_word(DOP_OR,true,DREG(FLAGS),DREG(EXIT)); //flags are marked for save
|
|
||||||
gen_releasereg(DREG(EXIT));
|
|
||||||
gen_releasereg(DREG(FLAGS));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dyn_savestate(DynState * state) {
|
|
||||||
for (Bitu i=0;i<G_MAX;i++) {
|
|
||||||
state->regs[i].flags=DynRegs[i].flags;
|
|
||||||
state->regs[i].genreg=DynRegs[i].genreg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dyn_loadstate(DynState * state) {
|
|
||||||
for (Bitu i=0;i<G_MAX;i++) {
|
|
||||||
gen_setupreg(&DynRegs[i],&state->regs[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dyn_synchstate(DynState * state) {
|
|
||||||
for (Bitu i=0;i<G_MAX;i++) {
|
|
||||||
gen_synchreg(&DynRegs[i],&state->regs[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dyn_saveregister(DynReg * src_reg, DynReg * dst_reg) {
|
|
||||||
dst_reg->flags=src_reg->flags;
|
|
||||||
dst_reg->genreg=src_reg->genreg;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dyn_restoreregister(DynReg * src_reg, DynReg * dst_reg) {
|
|
||||||
dst_reg->flags=src_reg->flags;
|
|
||||||
dst_reg->genreg=src_reg->genreg;
|
|
||||||
dst_reg->genreg->dynreg=dst_reg; // necessary when register has been released
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "core_dyn_x86/decoder.h"
|
|
||||||
|
|
||||||
#if defined (_MSC_VER)
|
|
||||||
#define DH_FPU_SAVE_REINIT \
|
|
||||||
{ \
|
|
||||||
__asm { \
|
|
||||||
__asm fnsave dyn_dh_fpu.state[0] \
|
|
||||||
} \
|
|
||||||
dyn_dh_fpu.state_used=false; \
|
|
||||||
dyn_dh_fpu.state[0]|=0x3f; \
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#define DH_FPU_SAVE_REINIT \
|
|
||||||
{ \
|
|
||||||
__asm__ volatile ( \
|
|
||||||
"fnsave %0 \n" \
|
|
||||||
: \
|
|
||||||
: "m" (dyn_dh_fpu.state[0]) \
|
|
||||||
: "memory" \
|
|
||||||
); \
|
|
||||||
dyn_dh_fpu.state_used=false; \
|
|
||||||
dyn_dh_fpu.state[0]|=0x3f; \
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
Bits CPU_Core_Dyn_X86_Run(void) {
|
|
||||||
/* Determine the linear address of CS:EIP */
|
|
||||||
restart_core:
|
|
||||||
PhysPt ip_point=SegPhys(cs)+reg_eip;
|
|
||||||
#if C_HEAVY_DEBUG
|
|
||||||
if (DEBUG_HeavyIsBreakpoint()) return debugCallback;
|
|
||||||
#endif
|
|
||||||
CodePageHandler * chandler=0;
|
|
||||||
if (GCC_UNLIKELY(MakeCodePage(ip_point,chandler))) {
|
|
||||||
CPU_Exception(cpu.exception.which,cpu.exception.error);
|
|
||||||
goto restart_core;
|
|
||||||
}
|
|
||||||
if (!chandler) {
|
|
||||||
if (dyn_dh_fpu.state_used) DH_FPU_SAVE_REINIT
|
|
||||||
return CPU_Core_Normal_Run();
|
|
||||||
}
|
|
||||||
/* Find correct Dynamic Block to run */
|
|
||||||
CacheBlock * block=chandler->FindCacheBlock(ip_point&4095);
|
|
||||||
if (!block) {
|
|
||||||
if (!chandler->invalidation_map || (chandler->invalidation_map[ip_point&4095]<4)) {
|
|
||||||
block=CreateCacheBlock(chandler,ip_point,32);
|
|
||||||
} else {
|
|
||||||
Bitu old_cycles=CPU_Cycles;
|
|
||||||
CPU_Cycles=1;
|
|
||||||
Bits nc_retcode=CPU_Core_Normal_Run();
|
|
||||||
if (dyn_dh_fpu.state_used) DH_FPU_SAVE_REINIT
|
|
||||||
if (!nc_retcode) {
|
|
||||||
CPU_Cycles=old_cycles-1;
|
|
||||||
goto restart_core;
|
|
||||||
}
|
|
||||||
CPU_CycleLeft+=old_cycles;
|
|
||||||
return nc_retcode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
run_block:
|
|
||||||
cache.block.running=0;
|
|
||||||
BlockReturn ret=gen_runcode(block->cache.start);
|
|
||||||
switch (ret) {
|
|
||||||
case BR_Iret:
|
|
||||||
#if C_HEAVY_DEBUG
|
|
||||||
if (DEBUG_HeavyIsBreakpoint()) {
|
|
||||||
if (dyn_dh_fpu.state_used) DH_FPU_SAVE_REINIT
|
|
||||||
return debugCallback;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
if (!GETFLAG(TF)) goto restart_core;
|
|
||||||
cpudecoder=CPU_Core_Dyn_X86_Trap_Run;
|
|
||||||
if (!dyn_dh_fpu.state_used) return CBRET_NONE;
|
|
||||||
DH_FPU_SAVE_REINIT
|
|
||||||
return CBRET_NONE;
|
|
||||||
case BR_Normal:
|
|
||||||
/* Maybe check if we staying in the same page? */
|
|
||||||
#if C_HEAVY_DEBUG
|
|
||||||
if (DEBUG_HeavyIsBreakpoint()) return debugCallback;
|
|
||||||
#endif
|
|
||||||
goto restart_core;
|
|
||||||
case BR_Cycles:
|
|
||||||
#if C_HEAVY_DEBUG
|
|
||||||
if (DEBUG_HeavyIsBreakpoint()) return debugCallback;
|
|
||||||
#endif
|
|
||||||
if (!dyn_dh_fpu.state_used) return CBRET_NONE;
|
|
||||||
DH_FPU_SAVE_REINIT
|
|
||||||
return CBRET_NONE;
|
|
||||||
case BR_CallBack:
|
|
||||||
if (!dyn_dh_fpu.state_used) return core_dyn.callback;
|
|
||||||
DH_FPU_SAVE_REINIT
|
|
||||||
return core_dyn.callback;
|
|
||||||
case BR_SMCBlock:
|
|
||||||
// LOG_MSG("selfmodification of running block at %x:%x",SegValue(cs),reg_eip);
|
|
||||||
cpu.exception.which=0;
|
|
||||||
// fallthrough, let the normal core handle the block-modifying instruction
|
|
||||||
case BR_Opcode:
|
|
||||||
CPU_CycleLeft+=CPU_Cycles;
|
|
||||||
CPU_Cycles=1;
|
|
||||||
if (dyn_dh_fpu.state_used) DH_FPU_SAVE_REINIT
|
|
||||||
return CPU_Core_Normal_Run();
|
|
||||||
#if (C_DEBUG)
|
|
||||||
case BR_OpcodeFull:
|
|
||||||
CPU_CycleLeft+=CPU_Cycles;
|
|
||||||
CPU_Cycles=1;
|
|
||||||
if (dyn_dh_fpu.state_used) DH_FPU_SAVE_REINIT
|
|
||||||
return CPU_Core_Full_Run();
|
|
||||||
#endif
|
|
||||||
case BR_Link1:
|
|
||||||
case BR_Link2:
|
|
||||||
{
|
|
||||||
Bitu temp_ip=SegPhys(cs)+reg_eip;
|
|
||||||
CodePageHandler * temp_handler=(CodePageHandler *)get_tlb_readhandler(temp_ip);
|
|
||||||
if (temp_handler->flags & PFLAG_HASCODE) {
|
|
||||||
block=temp_handler->FindCacheBlock(temp_ip & 4095);
|
|
||||||
if (!block) goto restart_core;
|
|
||||||
cache.block.running->LinkTo(ret==BR_Link2,block);
|
|
||||||
goto run_block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
goto restart_core;
|
|
||||||
}
|
|
||||||
if (dyn_dh_fpu.state_used) DH_FPU_SAVE_REINIT
|
|
||||||
return CBRET_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
Bits CPU_Core_Dyn_X86_Trap_Run(void) {
|
|
||||||
Bits oldCycles = CPU_Cycles;
|
|
||||||
CPU_Cycles = 1;
|
|
||||||
cpu.trap_skip = false;
|
|
||||||
|
|
||||||
Bits ret=CPU_Core_Normal_Run();
|
|
||||||
if (!cpu.trap_skip) CPU_HW_Interrupt(1);
|
|
||||||
CPU_Cycles = oldCycles-1;
|
|
||||||
cpudecoder = &CPU_Core_Dyn_X86_Run;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CPU_Core_Dyn_X86_Init(void) {
|
|
||||||
Bits i;
|
|
||||||
/* Setup the global registers and their flags */
|
|
||||||
for (i=0;i<G_MAX;i++) DynRegs[i].genreg=0;
|
|
||||||
DynRegs[G_EAX].data=®_eax;
|
|
||||||
DynRegs[G_EAX].flags=DYNFLG_HAS8|DYNFLG_HAS16|DYNFLG_LOAD|DYNFLG_SAVE;
|
|
||||||
DynRegs[G_ECX].data=®_ecx;
|
|
||||||
DynRegs[G_ECX].flags=DYNFLG_HAS8|DYNFLG_HAS16|DYNFLG_LOAD|DYNFLG_SAVE;
|
|
||||||
DynRegs[G_EDX].data=®_edx;
|
|
||||||
DynRegs[G_EDX].flags=DYNFLG_HAS8|DYNFLG_HAS16|DYNFLG_LOAD|DYNFLG_SAVE;
|
|
||||||
DynRegs[G_EBX].data=®_ebx;
|
|
||||||
DynRegs[G_EBX].flags=DYNFLG_HAS8|DYNFLG_HAS16|DYNFLG_LOAD|DYNFLG_SAVE;
|
|
||||||
|
|
||||||
DynRegs[G_EBP].data=®_ebp;
|
|
||||||
DynRegs[G_EBP].flags=DYNFLG_HAS16|DYNFLG_LOAD|DYNFLG_SAVE;
|
|
||||||
DynRegs[G_ESP].data=®_esp;
|
|
||||||
DynRegs[G_ESP].flags=DYNFLG_HAS16|DYNFLG_LOAD|DYNFLG_SAVE;
|
|
||||||
DynRegs[G_EDI].data=®_edi;
|
|
||||||
DynRegs[G_EDI].flags=DYNFLG_HAS16|DYNFLG_LOAD|DYNFLG_SAVE;
|
|
||||||
DynRegs[G_ESI].data=®_esi;
|
|
||||||
DynRegs[G_ESI].flags=DYNFLG_HAS16|DYNFLG_LOAD|DYNFLG_SAVE;
|
|
||||||
|
|
||||||
DynRegs[G_ES].data=&Segs.phys[es];
|
|
||||||
DynRegs[G_ES].flags=DYNFLG_LOAD|DYNFLG_SAVE;
|
|
||||||
DynRegs[G_CS].data=&Segs.phys[cs];
|
|
||||||
DynRegs[G_CS].flags=DYNFLG_LOAD|DYNFLG_SAVE;
|
|
||||||
DynRegs[G_SS].data=&Segs.phys[ss];
|
|
||||||
DynRegs[G_SS].flags=DYNFLG_LOAD|DYNFLG_SAVE;
|
|
||||||
DynRegs[G_DS].data=&Segs.phys[ds];
|
|
||||||
DynRegs[G_DS].flags=DYNFLG_LOAD|DYNFLG_SAVE;
|
|
||||||
DynRegs[G_FS].data=&Segs.phys[fs];
|
|
||||||
DynRegs[G_FS].flags=DYNFLG_LOAD|DYNFLG_SAVE;
|
|
||||||
DynRegs[G_GS].data=&Segs.phys[gs];
|
|
||||||
DynRegs[G_GS].flags=DYNFLG_LOAD|DYNFLG_SAVE;
|
|
||||||
|
|
||||||
DynRegs[G_FLAGS].data=®_flags;
|
|
||||||
DynRegs[G_FLAGS].flags=DYNFLG_LOAD|DYNFLG_SAVE;
|
|
||||||
|
|
||||||
DynRegs[G_NEWESP].data=&extra_regs.newesp;
|
|
||||||
DynRegs[G_NEWESP].flags=0;
|
|
||||||
|
|
||||||
DynRegs[G_EIP].data=®_eip;
|
|
||||||
DynRegs[G_EIP].flags=DYNFLG_LOAD|DYNFLG_SAVE;
|
|
||||||
|
|
||||||
DynRegs[G_EA].data=&extra_regs.ea;
|
|
||||||
DynRegs[G_EA].flags=0;
|
|
||||||
DynRegs[G_STACK].data=&extra_regs.stack;
|
|
||||||
DynRegs[G_STACK].flags=0;
|
|
||||||
DynRegs[G_CYCLES].data=&CPU_Cycles;
|
|
||||||
DynRegs[G_CYCLES].flags=DYNFLG_LOAD|DYNFLG_SAVE;
|
|
||||||
DynRegs[G_TMPB].data=&extra_regs.tmpb;
|
|
||||||
DynRegs[G_TMPB].flags=DYNFLG_HAS8|DYNFLG_HAS16;
|
|
||||||
DynRegs[G_TMPW].data=&extra_regs.tmpd;
|
|
||||||
DynRegs[G_TMPW].flags=DYNFLG_HAS16;
|
|
||||||
DynRegs[G_SHIFT].data=&extra_regs.shift;
|
|
||||||
DynRegs[G_SHIFT].flags=DYNFLG_HAS8|DYNFLG_HAS16;
|
|
||||||
DynRegs[G_EXIT].data=0;
|
|
||||||
DynRegs[G_EXIT].flags=DYNFLG_HAS16;
|
|
||||||
/* Init the generator */
|
|
||||||
gen_init();
|
|
||||||
|
|
||||||
/* Init the fpu state */
|
|
||||||
dyn_dh_fpu.dh_fpu_enabled=true;
|
|
||||||
dyn_dh_fpu.state_used=false;
|
|
||||||
dyn_dh_fpu.cw=0x37f;
|
|
||||||
#if defined (_MSC_VER)
|
|
||||||
__asm {
|
|
||||||
__asm finit
|
|
||||||
__asm fsave dyn_dh_fpu.state[0]
|
|
||||||
__asm fstcw dyn_dh_fpu.host_cw
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
__asm__ volatile (
|
|
||||||
"finit \n"
|
|
||||||
"fsave %0 \n"
|
|
||||||
"fstcw %1 \n"
|
|
||||||
:
|
|
||||||
: "m" (dyn_dh_fpu.state[0]), "m" (dyn_dh_fpu.host_cw)
|
|
||||||
: "memory"
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CPU_Core_Dyn_X86_Cache_Init(bool enable_cache) {
|
|
||||||
/* Initialize code cache and dynamic blocks */
|
|
||||||
cache_init(enable_cache);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CPU_Core_Dyn_X86_Cache_Close(void) {
|
|
||||||
cache_close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CPU_Core_Dyn_X86_SetFPUMode(bool dh_fpu) {
|
|
||||||
dyn_dh_fpu.dh_fpu_enabled=dh_fpu;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,2 +0,0 @@
|
|||||||
noinst_HEADERS = cache.h helpers.h decoder.h risc_x86.h string.h \
|
|
||||||
dyn_fpu.h dyn_fpu_dh.h
|
|
@ -1,528 +0,0 @@
|
|||||||
class CacheBlock {
|
|
||||||
public:
|
|
||||||
void Clear(void);
|
|
||||||
void LinkTo(Bitu index,CacheBlock * toblock) {
|
|
||||||
assert(toblock);
|
|
||||||
link[index].to=toblock;
|
|
||||||
link[index].next=toblock->link[index].from;
|
|
||||||
toblock->link[index].from=this;
|
|
||||||
}
|
|
||||||
struct {
|
|
||||||
Bit16u start,end; //Where the page is the original code
|
|
||||||
CodePageHandler * handler; //Page containing this code
|
|
||||||
} page;
|
|
||||||
struct {
|
|
||||||
Bit8u * start; //Where in the cache are we
|
|
||||||
Bitu size;
|
|
||||||
CacheBlock * next;
|
|
||||||
Bit8u * wmapmask;
|
|
||||||
Bit16u maskstart;
|
|
||||||
Bit16u masklen;
|
|
||||||
} cache;
|
|
||||||
struct {
|
|
||||||
Bitu index;
|
|
||||||
CacheBlock * next;
|
|
||||||
} hash;
|
|
||||||
struct {
|
|
||||||
CacheBlock * to;
|
|
||||||
CacheBlock * next;
|
|
||||||
CacheBlock * from;
|
|
||||||
} link[2];
|
|
||||||
CacheBlock * crossblock;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct {
|
|
||||||
struct {
|
|
||||||
CacheBlock * first;
|
|
||||||
CacheBlock * active;
|
|
||||||
CacheBlock * free;
|
|
||||||
CacheBlock * running;
|
|
||||||
} block;
|
|
||||||
Bit8u * pos;
|
|
||||||
CodePageHandler * free_pages;
|
|
||||||
CodePageHandler * used_pages;
|
|
||||||
CodePageHandler * last_page;
|
|
||||||
} cache;
|
|
||||||
|
|
||||||
static CacheBlock link_blocks[2];
|
|
||||||
|
|
||||||
class CodePageHandler : public PageHandler {
|
|
||||||
public:
|
|
||||||
CodePageHandler() {
|
|
||||||
invalidation_map=NULL;
|
|
||||||
}
|
|
||||||
void SetupAt(Bitu _phys_page,PageHandler * _old_pagehandler) {
|
|
||||||
phys_page=_phys_page;
|
|
||||||
old_pagehandler=_old_pagehandler;
|
|
||||||
flags=old_pagehandler->flags|PFLAG_HASCODE;
|
|
||||||
flags&=~PFLAG_WRITEABLE;
|
|
||||||
active_blocks=0;
|
|
||||||
active_count=16;
|
|
||||||
memset(&hash_map,0,sizeof(hash_map));
|
|
||||||
memset(&write_map,0,sizeof(write_map));
|
|
||||||
if (invalidation_map!=NULL) {
|
|
||||||
free(invalidation_map);
|
|
||||||
invalidation_map=NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bool InvalidateRange(Bitu start,Bitu end) {
|
|
||||||
Bits index=1+(end>>DYN_HASH_SHIFT);
|
|
||||||
bool is_current_block=false;
|
|
||||||
Bit32u ip_point=SegPhys(cs)+reg_eip;
|
|
||||||
ip_point=(PAGING_GetPhysicalPage(ip_point)-(phys_page<<12))+(ip_point&0xfff);
|
|
||||||
while (index>=0) {
|
|
||||||
Bitu map=0;
|
|
||||||
for (Bitu count=start;count<=end;count++) map+=write_map[count];
|
|
||||||
if (!map) return is_current_block;
|
|
||||||
CacheBlock * block=hash_map[index];
|
|
||||||
while (block) {
|
|
||||||
CacheBlock * nextblock=block->hash.next;
|
|
||||||
if (start<=block->page.end && end>=block->page.start) {
|
|
||||||
if (ip_point<=block->page.end && ip_point>=block->page.start) is_current_block=true;
|
|
||||||
block->Clear();
|
|
||||||
}
|
|
||||||
block=nextblock;
|
|
||||||
}
|
|
||||||
index--;
|
|
||||||
}
|
|
||||||
return is_current_block;
|
|
||||||
}
|
|
||||||
void writeb(PhysPt addr,Bitu val){
|
|
||||||
addr&=4095;
|
|
||||||
if (host_readb(hostmem+addr)==(Bit8u)val) return;
|
|
||||||
host_writeb(hostmem+addr,val);
|
|
||||||
if (!*(Bit8u*)&write_map[addr]) {
|
|
||||||
if (active_blocks) return;
|
|
||||||
active_count--;
|
|
||||||
if (!active_count) Release();
|
|
||||||
return;
|
|
||||||
} else if (!invalidation_map) {
|
|
||||||
invalidation_map=(Bit8u*)malloc(4096);
|
|
||||||
memset(invalidation_map,0,4096);
|
|
||||||
}
|
|
||||||
invalidation_map[addr]++;
|
|
||||||
InvalidateRange(addr,addr);
|
|
||||||
}
|
|
||||||
void writew(PhysPt addr,Bitu val){
|
|
||||||
addr&=4095;
|
|
||||||
if (host_readw(hostmem+addr)==(Bit16u)val) return;
|
|
||||||
host_writew(hostmem+addr,val);
|
|
||||||
if (!*(Bit16u*)&write_map[addr]) {
|
|
||||||
if (active_blocks) return;
|
|
||||||
active_count--;
|
|
||||||
if (!active_count) Release();
|
|
||||||
return;
|
|
||||||
} else if (!invalidation_map) {
|
|
||||||
invalidation_map=(Bit8u*)malloc(4096);
|
|
||||||
memset(invalidation_map,0,4096);
|
|
||||||
}
|
|
||||||
(*(Bit16u*)&invalidation_map[addr])+=0x101;
|
|
||||||
InvalidateRange(addr,addr+1);
|
|
||||||
}
|
|
||||||
void writed(PhysPt addr,Bitu val){
|
|
||||||
addr&=4095;
|
|
||||||
if (host_readd(hostmem+addr)==(Bit32u)val) return;
|
|
||||||
host_writed(hostmem+addr,val);
|
|
||||||
if (!*(Bit32u*)&write_map[addr]) {
|
|
||||||
if (active_blocks) return;
|
|
||||||
active_count--;
|
|
||||||
if (!active_count) Release();
|
|
||||||
return;
|
|
||||||
} else if (!invalidation_map) {
|
|
||||||
invalidation_map=(Bit8u*)malloc(4096);
|
|
||||||
memset(invalidation_map,0,4096);
|
|
||||||
}
|
|
||||||
(*(Bit32u*)&invalidation_map[addr])+=0x1010101;
|
|
||||||
InvalidateRange(addr,addr+3);
|
|
||||||
}
|
|
||||||
bool writeb_checked(PhysPt addr,Bitu val) {
|
|
||||||
addr&=4095;
|
|
||||||
if (host_readb(hostmem+addr)==(Bit8u)val) return false;
|
|
||||||
if (!*(Bit8u*)&write_map[addr]) {
|
|
||||||
if (!active_blocks) {
|
|
||||||
active_count--;
|
|
||||||
if (!active_count) Release();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!invalidation_map) {
|
|
||||||
invalidation_map=(Bit8u*)malloc(4096);
|
|
||||||
memset(invalidation_map,0,4096);
|
|
||||||
}
|
|
||||||
invalidation_map[addr]++;
|
|
||||||
if (InvalidateRange(addr,addr)) {
|
|
||||||
cpu.exception.which=SMC_CURRENT_BLOCK;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
host_writeb(hostmem+addr,val);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool writew_checked(PhysPt addr,Bitu val) {
|
|
||||||
addr&=4095;
|
|
||||||
if (host_readw(hostmem+addr)==(Bit16u)val) return false;
|
|
||||||
if (!*(Bit16u*)&write_map[addr]) {
|
|
||||||
if (!active_blocks) {
|
|
||||||
active_count--;
|
|
||||||
if (!active_count) Release();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!invalidation_map) {
|
|
||||||
invalidation_map=(Bit8u*)malloc(4096);
|
|
||||||
memset(invalidation_map,0,4096);
|
|
||||||
}
|
|
||||||
(*(Bit16u*)&invalidation_map[addr])+=0x101;
|
|
||||||
if (InvalidateRange(addr,addr+1)) {
|
|
||||||
cpu.exception.which=SMC_CURRENT_BLOCK;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
host_writew(hostmem+addr,val);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool writed_checked(PhysPt addr,Bitu val) {
|
|
||||||
addr&=4095;
|
|
||||||
if (host_readd(hostmem+addr)==(Bit32u)val) return false;
|
|
||||||
if (!*(Bit32u*)&write_map[addr]) {
|
|
||||||
if (!active_blocks) {
|
|
||||||
active_count--;
|
|
||||||
if (!active_count) Release();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!invalidation_map) {
|
|
||||||
invalidation_map=(Bit8u*)malloc(4096);
|
|
||||||
memset(invalidation_map,0,4096);
|
|
||||||
}
|
|
||||||
(*(Bit32u*)&invalidation_map[addr])+=0x1010101;
|
|
||||||
if (InvalidateRange(addr,addr+3)) {
|
|
||||||
cpu.exception.which=SMC_CURRENT_BLOCK;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
host_writed(hostmem+addr,val);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
void AddCacheBlock(CacheBlock * block) {
|
|
||||||
Bitu index=1+(block->page.start>>DYN_HASH_SHIFT);
|
|
||||||
block->hash.next=hash_map[index];
|
|
||||||
block->hash.index=index;
|
|
||||||
hash_map[index]=block;
|
|
||||||
block->page.handler=this;
|
|
||||||
active_blocks++;
|
|
||||||
}
|
|
||||||
void AddCrossBlock(CacheBlock * block) {
|
|
||||||
block->hash.next=hash_map[0];
|
|
||||||
block->hash.index=0;
|
|
||||||
hash_map[0]=block;
|
|
||||||
block->page.handler=this;
|
|
||||||
active_blocks++;
|
|
||||||
}
|
|
||||||
void DelCacheBlock(CacheBlock * block) {
|
|
||||||
active_blocks--;
|
|
||||||
active_count=16;
|
|
||||||
CacheBlock * * where=&hash_map[block->hash.index];
|
|
||||||
while (*where!=block) {
|
|
||||||
where=&((*where)->hash.next);
|
|
||||||
//Will crash if a block isn't found, which should never happen.
|
|
||||||
}
|
|
||||||
*where=block->hash.next;
|
|
||||||
if (GCC_UNLIKELY(block->cache.wmapmask!=NULL)) {
|
|
||||||
for (Bitu i=block->page.start;i<block->cache.maskstart;i++) {
|
|
||||||
if (write_map[i]) write_map[i]--;
|
|
||||||
}
|
|
||||||
Bitu maskct=0;
|
|
||||||
for (Bitu i=block->cache.maskstart;i<=block->page.end;i++,maskct++) {
|
|
||||||
if (write_map[i]) {
|
|
||||||
if ((maskct>=block->cache.masklen) || (!block->cache.wmapmask[maskct])) write_map[i]--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(block->cache.wmapmask);
|
|
||||||
block->cache.wmapmask=NULL;
|
|
||||||
} else {
|
|
||||||
for (Bitu i=block->page.start;i<=block->page.end;i++) {
|
|
||||||
if (write_map[i]) write_map[i]--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void Release(void) {
|
|
||||||
MEM_SetPageHandler(phys_page,1,old_pagehandler);
|
|
||||||
PAGING_ClearTLB();
|
|
||||||
if (prev) prev->next=next;
|
|
||||||
else cache.used_pages=next;
|
|
||||||
if (next) next->prev=prev;
|
|
||||||
else cache.last_page=prev;
|
|
||||||
next=cache.free_pages;
|
|
||||||
cache.free_pages=this;
|
|
||||||
prev=0;
|
|
||||||
}
|
|
||||||
void ClearRelease(void) {
|
|
||||||
for (Bitu index=0;index<(1+DYN_PAGE_HASH);index++) {
|
|
||||||
CacheBlock * block=hash_map[index];
|
|
||||||
while (block) {
|
|
||||||
CacheBlock * nextblock=block->hash.next;
|
|
||||||
block->page.handler=0; //No need, full clear
|
|
||||||
block->Clear();
|
|
||||||
block=nextblock;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Release();
|
|
||||||
}
|
|
||||||
CacheBlock * FindCacheBlock(Bitu start) {
|
|
||||||
CacheBlock * block=hash_map[1+(start>>DYN_HASH_SHIFT)];
|
|
||||||
while (block) {
|
|
||||||
if (block->page.start==start) return block;
|
|
||||||
block=block->hash.next;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
HostPt GetHostReadPt(Bitu phys_page) {
|
|
||||||
hostmem=old_pagehandler->GetHostReadPt(phys_page);
|
|
||||||
return hostmem;
|
|
||||||
}
|
|
||||||
HostPt GetHostWritePt(Bitu phys_page) {
|
|
||||||
return GetHostReadPt( phys_page );
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
Bit8u write_map[4096];
|
|
||||||
Bit8u * invalidation_map;
|
|
||||||
CodePageHandler * next, * prev;
|
|
||||||
private:
|
|
||||||
PageHandler * old_pagehandler;
|
|
||||||
CacheBlock * hash_map[1+DYN_PAGE_HASH];
|
|
||||||
Bitu active_blocks;
|
|
||||||
Bitu active_count;
|
|
||||||
HostPt hostmem;
|
|
||||||
Bitu phys_page;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE void cache_addunsedblock(CacheBlock * block) {
|
|
||||||
block->cache.next=cache.block.free;
|
|
||||||
cache.block.free=block;
|
|
||||||
}
|
|
||||||
|
|
||||||
static CacheBlock * cache_getblock(void) {
|
|
||||||
CacheBlock * ret=cache.block.free;
|
|
||||||
if (!ret) E_Exit("Ran out of CacheBlocks" );
|
|
||||||
cache.block.free=ret->cache.next;
|
|
||||||
ret->cache.next=0;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CacheBlock::Clear(void) {
|
|
||||||
Bitu ind;
|
|
||||||
/* Check if this is not a cross page block */
|
|
||||||
if (hash.index) for (ind=0;ind<2;ind++) {
|
|
||||||
CacheBlock * fromlink=link[ind].from;
|
|
||||||
link[ind].from=0;
|
|
||||||
while (fromlink) {
|
|
||||||
CacheBlock * nextlink=fromlink->link[ind].next;
|
|
||||||
fromlink->link[ind].next=0;
|
|
||||||
fromlink->link[ind].to=&link_blocks[ind];
|
|
||||||
fromlink=nextlink;
|
|
||||||
}
|
|
||||||
if (link[ind].to!=&link_blocks[ind]) {
|
|
||||||
CacheBlock * * wherelink=&link[ind].to->link[ind].from;
|
|
||||||
while (*wherelink != this && *wherelink) {
|
|
||||||
wherelink = &(*wherelink)->link[ind].next;
|
|
||||||
}
|
|
||||||
if(*wherelink)
|
|
||||||
*wherelink = (*wherelink)->link[ind].next;
|
|
||||||
else
|
|
||||||
LOG(LOG_CPU,LOG_ERROR)("Cache anomaly. please investigate");
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
cache_addunsedblock(this);
|
|
||||||
if (crossblock) {
|
|
||||||
crossblock->crossblock=0;
|
|
||||||
crossblock->Clear();
|
|
||||||
crossblock=0;
|
|
||||||
}
|
|
||||||
if (page.handler) {
|
|
||||||
page.handler->DelCacheBlock(this);
|
|
||||||
page.handler=0;
|
|
||||||
}
|
|
||||||
if (cache.wmapmask){
|
|
||||||
free(cache.wmapmask);
|
|
||||||
cache.wmapmask=NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static CacheBlock * cache_openblock(void) {
|
|
||||||
CacheBlock * block=cache.block.active;
|
|
||||||
/* check for enough space in this block */
|
|
||||||
Bitu size=block->cache.size;
|
|
||||||
CacheBlock * nextblock=block->cache.next;
|
|
||||||
if (block->page.handler)
|
|
||||||
block->Clear();
|
|
||||||
while (size<CACHE_MAXSIZE) {
|
|
||||||
if (!nextblock)
|
|
||||||
goto skipresize;
|
|
||||||
size+=nextblock->cache.size;
|
|
||||||
CacheBlock * tempblock=nextblock->cache.next;
|
|
||||||
if (nextblock->page.handler)
|
|
||||||
nextblock->Clear();
|
|
||||||
cache_addunsedblock(nextblock);
|
|
||||||
nextblock=tempblock;
|
|
||||||
}
|
|
||||||
skipresize:
|
|
||||||
block->cache.size=size;
|
|
||||||
block->cache.next=nextblock;
|
|
||||||
cache.pos=block->cache.start;
|
|
||||||
return block;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cache_closeblock(void) {
|
|
||||||
CacheBlock * block=cache.block.active;
|
|
||||||
block->link[0].to=&link_blocks[0];
|
|
||||||
block->link[1].to=&link_blocks[1];
|
|
||||||
block->link[0].from=0;
|
|
||||||
block->link[1].from=0;
|
|
||||||
block->link[0].next=0;
|
|
||||||
block->link[1].next=0;
|
|
||||||
/* Close the block with correct alignments */
|
|
||||||
Bitu written=cache.pos-block->cache.start;
|
|
||||||
if (written>block->cache.size) {
|
|
||||||
if (!block->cache.next) {
|
|
||||||
if (written>block->cache.size+CACHE_MAXSIZE) E_Exit("CacheBlock overrun 1 %d",written-block->cache.size);
|
|
||||||
} else E_Exit("CacheBlock overrun 2 written %d size %d",written,block->cache.size);
|
|
||||||
} else {
|
|
||||||
Bitu new_size;
|
|
||||||
Bitu left=block->cache.size-written;
|
|
||||||
/* Smaller than cache align then don't bother to resize */
|
|
||||||
if (left>CACHE_ALIGN) {
|
|
||||||
new_size=((written-1)|(CACHE_ALIGN-1))+1;
|
|
||||||
CacheBlock * newblock=cache_getblock();
|
|
||||||
newblock->cache.start=block->cache.start+new_size;
|
|
||||||
newblock->cache.size=block->cache.size-new_size;
|
|
||||||
newblock->cache.next=block->cache.next;
|
|
||||||
block->cache.next=newblock;
|
|
||||||
block->cache.size=new_size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Advance the active block pointer */
|
|
||||||
if (!block->cache.next) {
|
|
||||||
// LOG_MSG("Cache full restarting");
|
|
||||||
cache.block.active=cache.block.first;
|
|
||||||
} else {
|
|
||||||
cache.block.active=block->cache.next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void cache_addb(Bit8u val) {
|
|
||||||
*cache.pos++=val;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void cache_addw(Bit16u val) {
|
|
||||||
*(Bit16u*)cache.pos=val;
|
|
||||||
cache.pos+=2;
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void cache_addd(Bit32u val) {
|
|
||||||
*(Bit32u*)cache.pos=val;
|
|
||||||
cache.pos+=4;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void gen_return(BlockReturn retcode);
|
|
||||||
|
|
||||||
static Bit8u * cache_code_start_ptr=NULL;
|
|
||||||
static Bit8u * cache_code=NULL;
|
|
||||||
static Bit8u * cache_code_link_blocks=NULL;
|
|
||||||
static CacheBlock * cache_blocks=NULL;
|
|
||||||
|
|
||||||
/* Define temporary pagesize so the MPROTECT case and the regular case share as much code as possible */
|
|
||||||
#if (C_HAVE_MPROTECT)
|
|
||||||
#define PAGESIZE_TEMP PAGESIZE
|
|
||||||
#else
|
|
||||||
#define PAGESIZE_TEMP 4096
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static bool cache_initialized = false;
|
|
||||||
|
|
||||||
static void cache_init(bool enable) {
|
|
||||||
Bits i;
|
|
||||||
if (enable) {
|
|
||||||
if (cache_initialized) return;
|
|
||||||
cache_initialized = true;
|
|
||||||
if (cache_blocks == NULL) {
|
|
||||||
cache_blocks=(CacheBlock*)malloc(CACHE_BLOCKS*sizeof(CacheBlock));
|
|
||||||
if(!cache_blocks) E_Exit("Allocating cache_blocks has failed");
|
|
||||||
memset(cache_blocks,0,sizeof(CacheBlock)*CACHE_BLOCKS);
|
|
||||||
cache.block.free=&cache_blocks[0];
|
|
||||||
for (i=0;i<CACHE_BLOCKS-1;i++) {
|
|
||||||
cache_blocks[i].link[0].to=(CacheBlock *)1;
|
|
||||||
cache_blocks[i].link[1].to=(CacheBlock *)1;
|
|
||||||
cache_blocks[i].cache.next=&cache_blocks[i+1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (cache_code_start_ptr==NULL) {
|
|
||||||
#if defined (WIN32)
|
|
||||||
cache_code_start_ptr=(Bit8u*)VirtualAlloc(0,CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP-1+PAGESIZE_TEMP,
|
|
||||||
MEM_COMMIT,PAGE_EXECUTE_READWRITE);
|
|
||||||
if (!cache_code_start_ptr)
|
|
||||||
cache_code_start_ptr=(Bit8u*)malloc(CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP-1+PAGESIZE_TEMP);
|
|
||||||
#else
|
|
||||||
cache_code_start_ptr=(Bit8u*)malloc(CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP-1+PAGESIZE_TEMP);
|
|
||||||
#endif
|
|
||||||
if(!cache_code_start_ptr) E_Exit("Allocating dynamic core cache memory failed");
|
|
||||||
|
|
||||||
cache_code=(Bit8u*)(((int)cache_code_start_ptr + PAGESIZE_TEMP-1) & ~(PAGESIZE_TEMP-1)); //MEM LEAK. store old pointer if you want to free it.
|
|
||||||
|
|
||||||
cache_code_link_blocks=cache_code;
|
|
||||||
cache_code+=PAGESIZE_TEMP;
|
|
||||||
|
|
||||||
#if (C_HAVE_MPROTECT)
|
|
||||||
if(mprotect(cache_code_link_blocks,CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP,PROT_WRITE|PROT_READ|PROT_EXEC))
|
|
||||||
LOG_MSG("Setting excute permission on the code cache has failed!");
|
|
||||||
#endif
|
|
||||||
CacheBlock * block=cache_getblock();
|
|
||||||
cache.block.first=block;
|
|
||||||
cache.block.active=block;
|
|
||||||
block->cache.start=&cache_code[0];
|
|
||||||
block->cache.size=CACHE_TOTAL;
|
|
||||||
block->cache.next=0; //Last block in the list
|
|
||||||
}
|
|
||||||
/* Setup the default blocks for block linkage returns */
|
|
||||||
cache.pos=&cache_code_link_blocks[0];
|
|
||||||
link_blocks[0].cache.start=cache.pos;
|
|
||||||
gen_return(BR_Link1);
|
|
||||||
cache.pos=&cache_code_link_blocks[32];
|
|
||||||
link_blocks[1].cache.start=cache.pos;
|
|
||||||
gen_return(BR_Link2);
|
|
||||||
cache.free_pages=0;
|
|
||||||
cache.last_page=0;
|
|
||||||
cache.used_pages=0;
|
|
||||||
/* Setup the code pages */
|
|
||||||
for (i=0;i<CACHE_PAGES;i++) {
|
|
||||||
CodePageHandler * newpage=new CodePageHandler();
|
|
||||||
newpage->next=cache.free_pages;
|
|
||||||
cache.free_pages=newpage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cache_close(void) {
|
|
||||||
/* for (;;) {
|
|
||||||
if (cache.used_pages) {
|
|
||||||
CodePageHandler * cpage=cache.used_pages;
|
|
||||||
CodePageHandler * npage=cache.used_pages->next;
|
|
||||||
cpage->ClearRelease();
|
|
||||||
delete cpage;
|
|
||||||
cache.used_pages=npage;
|
|
||||||
} else break;
|
|
||||||
}
|
|
||||||
if (cache_blocks != NULL) {
|
|
||||||
free(cache_blocks);
|
|
||||||
cache_blocks = NULL;
|
|
||||||
}
|
|
||||||
if (cache_code_start_ptr != NULL) {
|
|
||||||
### care: under windows VirtualFree() has to be used if
|
|
||||||
### VirtualAlloc was used for memory allocation
|
|
||||||
free(cache_code_start_ptr);
|
|
||||||
cache_code_start_ptr = NULL;
|
|
||||||
}
|
|
||||||
cache_code = NULL;
|
|
||||||
cache_code_link_blocks = NULL;
|
|
||||||
cache_initialized = false; */
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,665 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2002-2007 The DOSBox Team
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* $Id: dyn_fpu.h,v 1.3 2007/06/14 17:47:24 c2woody Exp $ */
|
|
||||||
|
|
||||||
#include "dosbox.h"
|
|
||||||
#if C_FPU
|
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
#include <float.h>
|
|
||||||
#include "cross.h"
|
|
||||||
#include "mem.h"
|
|
||||||
#include "fpu.h"
|
|
||||||
#include "cpu.h"
|
|
||||||
|
|
||||||
|
|
||||||
static void FPU_FDECSTP(){
|
|
||||||
TOP = (TOP - 1) & 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void FPU_FINCSTP(){
|
|
||||||
TOP = (TOP + 1) & 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void FPU_FNSTCW(PhysPt addr){
|
|
||||||
mem_writew(addr,fpu.cw);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void FPU_FFREE(Bitu st) {
|
|
||||||
fpu.tags[st]=TAG_Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if C_FPU_X86
|
|
||||||
#include "../../fpu/fpu_instructions_x86.h"
|
|
||||||
#else
|
|
||||||
#include "../../fpu/fpu_instructions.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#define dyn_fpu_top() { \
|
|
||||||
gen_protectflags(); \
|
|
||||||
gen_load_host(&TOP,DREG(EA),4); \
|
|
||||||
gen_dop_word_imm(DOP_ADD,true,DREG(EA),decode.modrm.rm); \
|
|
||||||
gen_dop_word_imm(DOP_AND,true,DREG(EA),7); \
|
|
||||||
gen_load_host(&TOP,DREG(TMPB),4); \
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dyn_eatree() {
|
|
||||||
Bitu group=(decode.modrm.val >> 3) & 7;
|
|
||||||
switch (group){
|
|
||||||
case 0x00: /* FADD ST,STi */
|
|
||||||
gen_call_function((void*)&FPU_FADD_EA,"%Ddr",DREG(TMPB));
|
|
||||||
break;
|
|
||||||
case 0x01: /* FMUL ST,STi */
|
|
||||||
gen_call_function((void*)&FPU_FMUL_EA,"%Ddr",DREG(TMPB));
|
|
||||||
break;
|
|
||||||
case 0x02: /* FCOM STi */
|
|
||||||
gen_call_function((void*)&FPU_FCOM_EA,"%Ddr",DREG(TMPB));
|
|
||||||
break;
|
|
||||||
case 0x03: /* FCOMP STi */
|
|
||||||
gen_call_function((void*)&FPU_FCOM_EA,"%Ddr",DREG(TMPB));
|
|
||||||
gen_call_function((void*)&FPU_FPOP,"");
|
|
||||||
break;
|
|
||||||
case 0x04: /* FSUB ST,STi */
|
|
||||||
gen_call_function((void*)&FPU_FSUB_EA,"%Ddr",DREG(TMPB));
|
|
||||||
break;
|
|
||||||
case 0x05: /* FSUBR ST,STi */
|
|
||||||
gen_call_function((void*)&FPU_FSUBR_EA,"%Ddr",DREG(TMPB));
|
|
||||||
break;
|
|
||||||
case 0x06: /* FDIV ST,STi */
|
|
||||||
gen_call_function((void*)&FPU_FDIV_EA,"%Ddr",DREG(TMPB));
|
|
||||||
break;
|
|
||||||
case 0x07: /* FDIVR ST,STi */
|
|
||||||
gen_call_function((void*)&FPU_FDIVR_EA,"%Ddr",DREG(TMPB));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dyn_fpu_esc0(){
|
|
||||||
dyn_get_modrm();
|
|
||||||
if (decode.modrm.val >= 0xc0) {
|
|
||||||
dyn_fpu_top();
|
|
||||||
Bitu group=(decode.modrm.val >> 3) & 7;
|
|
||||||
Bitu sub=(decode.modrm.val & 7);
|
|
||||||
switch (group){
|
|
||||||
case 0x00: //FADD ST,STi /
|
|
||||||
gen_call_function((void*)&FPU_FADD,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
|
|
||||||
break;
|
|
||||||
case 0x01: // FMUL ST,STi /
|
|
||||||
gen_call_function((void*)&FPU_FMUL,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
|
|
||||||
break;
|
|
||||||
case 0x02: // FCOM STi /
|
|
||||||
gen_call_function((void*)&FPU_FCOM,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
|
|
||||||
break;
|
|
||||||
case 0x03: // FCOMP STi /
|
|
||||||
gen_call_function((void*)&FPU_FCOM,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
|
|
||||||
gen_call_function((void*)&FPU_FPOP,"");
|
|
||||||
break;
|
|
||||||
case 0x04: // FSUB ST,STi /
|
|
||||||
gen_call_function((void*)&FPU_FSUB,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
|
|
||||||
break;
|
|
||||||
case 0x05: // FSUBR ST,STi /
|
|
||||||
gen_call_function((void*)&FPU_FSUBR,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
|
|
||||||
break;
|
|
||||||
case 0x06: // FDIV ST,STi /
|
|
||||||
gen_call_function((void*)&FPU_FDIV,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
|
|
||||||
break;
|
|
||||||
case 0x07: // FDIVR ST,STi /
|
|
||||||
gen_call_function((void*)&FPU_FDIVR,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dyn_fill_ea();
|
|
||||||
gen_call_function((void*)&FPU_FLD_F32_EA,"%Ddr",DREG(EA));
|
|
||||||
gen_load_host(&TOP,DREG(TMPB),4);
|
|
||||||
dyn_eatree();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dyn_fpu_esc1(){
|
|
||||||
dyn_get_modrm();
|
|
||||||
if (decode.modrm.val >= 0xc0) {
|
|
||||||
Bitu group=(decode.modrm.val >> 3) & 7;
|
|
||||||
Bitu sub=(decode.modrm.val & 7);
|
|
||||||
switch (group){
|
|
||||||
case 0x00: /* FLD STi */
|
|
||||||
gen_protectflags();
|
|
||||||
gen_load_host(&TOP,DREG(EA),4);
|
|
||||||
gen_dop_word_imm(DOP_ADD,true,DREG(EA),decode.modrm.rm);
|
|
||||||
gen_dop_word_imm(DOP_AND,true,DREG(EA),7);
|
|
||||||
gen_call_function((void*)&FPU_PREP_PUSH,"");
|
|
||||||
gen_load_host(&TOP,DREG(TMPB),4);
|
|
||||||
gen_call_function((void*)&FPU_FST,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
|
|
||||||
break;
|
|
||||||
case 0x01: /* FXCH STi */
|
|
||||||
dyn_fpu_top();
|
|
||||||
gen_call_function((void*)&FPU_FXCH,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
|
|
||||||
break;
|
|
||||||
case 0x02: /* FNOP */
|
|
||||||
gen_call_function((void*)&FPU_FNOP,"");
|
|
||||||
break;
|
|
||||||
case 0x03: /* FSTP STi */
|
|
||||||
dyn_fpu_top();
|
|
||||||
gen_call_function((void*)&FPU_FST,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
|
|
||||||
gen_call_function((void*)&FPU_FPOP,"");
|
|
||||||
break;
|
|
||||||
case 0x04:
|
|
||||||
switch(sub){
|
|
||||||
case 0x00: /* FCHS */
|
|
||||||
gen_call_function((void*)&FPU_FCHS,"");
|
|
||||||
break;
|
|
||||||
case 0x01: /* FABS */
|
|
||||||
gen_call_function((void*)&FPU_FABS,"");
|
|
||||||
break;
|
|
||||||
case 0x02: /* UNKNOWN */
|
|
||||||
case 0x03: /* ILLEGAL */
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub);
|
|
||||||
break;
|
|
||||||
case 0x04: /* FTST */
|
|
||||||
gen_call_function((void*)&FPU_FTST,"");
|
|
||||||
break;
|
|
||||||
case 0x05: /* FXAM */
|
|
||||||
gen_call_function((void*)&FPU_FXAM,"");
|
|
||||||
break;
|
|
||||||
case 0x06: /* FTSTP (cyrix)*/
|
|
||||||
case 0x07: /* UNKNOWN */
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 0x05:
|
|
||||||
switch(sub){
|
|
||||||
case 0x00: /* FLD1 */
|
|
||||||
gen_call_function((void*)&FPU_FLD1,"");
|
|
||||||
break;
|
|
||||||
case 0x01: /* FLDL2T */
|
|
||||||
gen_call_function((void*)&FPU_FLDL2T,"");
|
|
||||||
break;
|
|
||||||
case 0x02: /* FLDL2E */
|
|
||||||
gen_call_function((void*)&FPU_FLDL2E,"");
|
|
||||||
break;
|
|
||||||
case 0x03: /* FLDPI */
|
|
||||||
gen_call_function((void*)&FPU_FLDPI,"");
|
|
||||||
break;
|
|
||||||
case 0x04: /* FLDLG2 */
|
|
||||||
gen_call_function((void*)&FPU_FLDLG2,"");
|
|
||||||
break;
|
|
||||||
case 0x05: /* FLDLN2 */
|
|
||||||
gen_call_function((void*)&FPU_FLDLN2,"");
|
|
||||||
break;
|
|
||||||
case 0x06: /* FLDZ*/
|
|
||||||
gen_call_function((void*)&FPU_FLDZ,"");
|
|
||||||
break;
|
|
||||||
case 0x07: /* ILLEGAL */
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 0x06:
|
|
||||||
switch(sub){
|
|
||||||
case 0x00: /* F2XM1 */
|
|
||||||
gen_call_function((void*)&FPU_F2XM1,"");
|
|
||||||
break;
|
|
||||||
case 0x01: /* FYL2X */
|
|
||||||
gen_call_function((void*)&FPU_FYL2X,"");
|
|
||||||
break;
|
|
||||||
case 0x02: /* FPTAN */
|
|
||||||
gen_call_function((void*)&FPU_FPTAN,"");
|
|
||||||
break;
|
|
||||||
case 0x03: /* FPATAN */
|
|
||||||
gen_call_function((void*)&FPU_FPATAN,"");
|
|
||||||
break;
|
|
||||||
case 0x04: /* FXTRACT */
|
|
||||||
gen_call_function((void*)&FPU_FXTRACT,"");
|
|
||||||
break;
|
|
||||||
case 0x05: /* FPREM1 */
|
|
||||||
gen_call_function((void*)&FPU_FPREM1,"");
|
|
||||||
break;
|
|
||||||
case 0x06: /* FDECSTP */
|
|
||||||
gen_call_function((void*)&FPU_FDECSTP,"");
|
|
||||||
break;
|
|
||||||
case 0x07: /* FINCSTP */
|
|
||||||
gen_call_function((void*)&FPU_FINCSTP,"");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 0x07:
|
|
||||||
switch(sub){
|
|
||||||
case 0x00: /* FPREM */
|
|
||||||
gen_call_function((void*)&FPU_FPREM,"");
|
|
||||||
break;
|
|
||||||
case 0x01: /* FYL2XP1 */
|
|
||||||
gen_call_function((void*)&FPU_FYL2XP1,"");
|
|
||||||
break;
|
|
||||||
case 0x02: /* FSQRT */
|
|
||||||
gen_call_function((void*)&FPU_FSQRT,"");
|
|
||||||
break;
|
|
||||||
case 0x03: /* FSINCOS */
|
|
||||||
gen_call_function((void*)&FPU_FSINCOS,"");
|
|
||||||
break;
|
|
||||||
case 0x04: /* FRNDINT */
|
|
||||||
gen_call_function((void*)&FPU_FRNDINT,"");
|
|
||||||
break;
|
|
||||||
case 0x05: /* FSCALE */
|
|
||||||
gen_call_function((void*)&FPU_FSCALE,"");
|
|
||||||
break;
|
|
||||||
case 0x06: /* FSIN */
|
|
||||||
gen_call_function((void*)&FPU_FSIN,"");
|
|
||||||
break;
|
|
||||||
case 0x07: /* FCOS */
|
|
||||||
gen_call_function((void*)&FPU_FCOS,"");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",group,sub);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Bitu group=(decode.modrm.val >> 3) & 7;
|
|
||||||
Bitu sub=(decode.modrm.val & 7);
|
|
||||||
dyn_fill_ea();
|
|
||||||
switch(group){
|
|
||||||
case 0x00: /* FLD float*/
|
|
||||||
gen_protectflags();
|
|
||||||
gen_call_function((void*)&FPU_PREP_PUSH,"");
|
|
||||||
gen_load_host(&TOP,DREG(TMPB),4);
|
|
||||||
gen_call_function((void*)&FPU_FLD_F32,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
|
|
||||||
break;
|
|
||||||
case 0x01: /* UNKNOWN */
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC EA 1:Unhandled group %d subfunction %d",group,sub);
|
|
||||||
break;
|
|
||||||
case 0x02: /* FST float*/
|
|
||||||
gen_call_function((void*)&FPU_FST_F32,"%Ddr",DREG(EA));
|
|
||||||
break;
|
|
||||||
case 0x03: /* FSTP float*/
|
|
||||||
gen_call_function((void*)&FPU_FST_F32,"%Ddr",DREG(EA));
|
|
||||||
gen_call_function((void*)&FPU_FPOP,"");
|
|
||||||
break;
|
|
||||||
case 0x04: /* FLDENV */
|
|
||||||
gen_call_function((void*)&FPU_FLDENV,"%Ddr",DREG(EA));
|
|
||||||
break;
|
|
||||||
case 0x05: /* FLDCW */
|
|
||||||
gen_call_function((void *)&FPU_FLDCW,"%Ddr",DREG(EA));
|
|
||||||
break;
|
|
||||||
case 0x06: /* FSTENV */
|
|
||||||
gen_call_function((void *)&FPU_FSTENV,"%Ddr",DREG(EA));
|
|
||||||
break;
|
|
||||||
case 0x07: /* FNSTCW*/
|
|
||||||
gen_call_function((void *)&FPU_FNSTCW,"%Ddr",DREG(EA));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC EA 1:Unhandled group %d subfunction %d",group,sub);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dyn_fpu_esc2(){
|
|
||||||
dyn_get_modrm();
|
|
||||||
if (decode.modrm.val >= 0xc0) {
|
|
||||||
Bitu group=(decode.modrm.val >> 3) & 7;
|
|
||||||
Bitu sub=(decode.modrm.val & 7);
|
|
||||||
switch(group){
|
|
||||||
case 0x05:
|
|
||||||
switch(sub){
|
|
||||||
case 0x01: /* FUCOMPP */
|
|
||||||
gen_protectflags();
|
|
||||||
gen_load_host(&TOP,DREG(EA),4);
|
|
||||||
gen_dop_word_imm(DOP_ADD,true,DREG(EA),1);
|
|
||||||
gen_dop_word_imm(DOP_AND,true,DREG(EA),7);
|
|
||||||
gen_load_host(&TOP,DREG(TMPB),4);
|
|
||||||
gen_call_function((void *)&FPU_FUCOM,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
|
|
||||||
gen_call_function((void *)&FPU_FPOP,"");
|
|
||||||
gen_call_function((void *)&FPU_FPOP,"");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 2:Unhandled group %d subfunction %d",group,sub);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 2:Unhandled group %d subfunction %d",group,sub);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dyn_fill_ea();
|
|
||||||
gen_call_function((void*)&FPU_FLD_I32_EA,"%Ddr",DREG(EA));
|
|
||||||
gen_load_host(&TOP,DREG(TMPB),4);
|
|
||||||
dyn_eatree();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dyn_fpu_esc3(){
|
|
||||||
dyn_get_modrm();
|
|
||||||
if (decode.modrm.val >= 0xc0) {
|
|
||||||
Bitu group=(decode.modrm.val >> 3) & 7;
|
|
||||||
Bitu sub=(decode.modrm.val & 7);
|
|
||||||
switch (group) {
|
|
||||||
case 0x04:
|
|
||||||
switch (sub) {
|
|
||||||
case 0x00: //FNENI
|
|
||||||
case 0x01: //FNDIS
|
|
||||||
LOG(LOG_FPU,LOG_ERROR)("8087 only fpu code used esc 3: group 4: subfuntion :%d",sub);
|
|
||||||
break;
|
|
||||||
case 0x02: //FNCLEX FCLEX
|
|
||||||
gen_call_function((void*)&FPU_FCLEX,"");
|
|
||||||
break;
|
|
||||||
case 0x03: //FNINIT FINIT
|
|
||||||
gen_call_function((void*)&FPU_FINIT,"");
|
|
||||||
break;
|
|
||||||
case 0x04: //FNSETPM
|
|
||||||
case 0x05: //FRSTPM
|
|
||||||
// LOG(LOG_FPU,LOG_ERROR)("80267 protected mode (un)set. Nothing done");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
E_Exit("ESC 3:ILLEGAL OPCODE group %d subfunction %d",group,sub);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 3:Unhandled group %d subfunction %d",group,sub);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Bitu group=(decode.modrm.val >> 3) & 7;
|
|
||||||
Bitu sub=(decode.modrm.val & 7);
|
|
||||||
dyn_fill_ea();
|
|
||||||
switch(group){
|
|
||||||
case 0x00: /* FILD */
|
|
||||||
gen_call_function((void*)&FPU_PREP_PUSH,"");
|
|
||||||
gen_protectflags();
|
|
||||||
gen_load_host(&TOP,DREG(TMPB),4);
|
|
||||||
gen_call_function((void*)&FPU_FLD_I32,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
|
|
||||||
break;
|
|
||||||
case 0x01: /* FISTTP */
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 3 EA:Unhandled group %d subfunction %d",group,sub);
|
|
||||||
break;
|
|
||||||
case 0x02: /* FIST */
|
|
||||||
gen_call_function((void*)&FPU_FST_I32,"%Ddr",DREG(EA));
|
|
||||||
break;
|
|
||||||
case 0x03: /* FISTP */
|
|
||||||
gen_call_function((void*)&FPU_FST_I32,"%Ddr",DREG(EA));
|
|
||||||
gen_call_function((void*)&FPU_FPOP,"");
|
|
||||||
break;
|
|
||||||
case 0x05: /* FLD 80 Bits Real */
|
|
||||||
gen_call_function((void*)&FPU_PREP_PUSH,"");
|
|
||||||
gen_call_function((void*)&FPU_FLD_F80,"%Ddr",DREG(EA));
|
|
||||||
break;
|
|
||||||
case 0x07: /* FSTP 80 Bits Real */
|
|
||||||
gen_call_function((void*)&FPU_FST_F80,"%Ddr",DREG(EA));
|
|
||||||
gen_call_function((void*)&FPU_FPOP,"");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 3 EA:Unhandled group %d subfunction %d",group,sub);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dyn_fpu_esc4(){
|
|
||||||
dyn_get_modrm();
|
|
||||||
Bitu group=(decode.modrm.val >> 3) & 7;
|
|
||||||
Bitu sub=(decode.modrm.val & 7);
|
|
||||||
if (decode.modrm.val >= 0xc0) {
|
|
||||||
dyn_fpu_top();
|
|
||||||
switch(group){
|
|
||||||
case 0x00: /* FADD STi,ST*/
|
|
||||||
gen_call_function((void*)&FPU_FADD,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
|
|
||||||
break;
|
|
||||||
case 0x01: /* FMUL STi,ST*/
|
|
||||||
gen_call_function((void*)&FPU_FMUL,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
|
|
||||||
break;
|
|
||||||
case 0x02: /* FCOM*/
|
|
||||||
gen_call_function((void*)&FPU_FCOM,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
|
|
||||||
break;
|
|
||||||
case 0x03: /* FCOMP*/
|
|
||||||
gen_call_function((void*)&FPU_FCOM,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
|
|
||||||
gen_call_function((void*)&FPU_FPOP,"");
|
|
||||||
break;
|
|
||||||
case 0x04: /* FSUBR STi,ST*/
|
|
||||||
gen_call_function((void*)&FPU_FSUBR,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
|
|
||||||
break;
|
|
||||||
case 0x05: /* FSUB STi,ST*/
|
|
||||||
gen_call_function((void*)&FPU_FSUB,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
|
|
||||||
break;
|
|
||||||
case 0x06: /* FDIVR STi,ST*/
|
|
||||||
gen_call_function((void*)&FPU_FDIVR,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
|
|
||||||
break;
|
|
||||||
case 0x07: /* FDIV STi,ST*/
|
|
||||||
gen_call_function((void*)&FPU_FDIV,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dyn_fill_ea();
|
|
||||||
gen_call_function((void*)&FPU_FLD_F64_EA,"%Ddr",DREG(EA));
|
|
||||||
gen_load_host(&TOP,DREG(TMPB),4);
|
|
||||||
dyn_eatree();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dyn_fpu_esc5(){
|
|
||||||
dyn_get_modrm();
|
|
||||||
Bitu group=(decode.modrm.val >> 3) & 7;
|
|
||||||
Bitu sub=(decode.modrm.val & 7);
|
|
||||||
if (decode.modrm.val >= 0xc0) {
|
|
||||||
dyn_fpu_top();
|
|
||||||
switch(group){
|
|
||||||
case 0x00: /* FFREE STi */
|
|
||||||
gen_call_function((void*)&FPU_FFREE,"%Ddr",DREG(EA));
|
|
||||||
break;
|
|
||||||
case 0x01: /* FXCH STi*/
|
|
||||||
gen_call_function((void*)&FPU_FXCH,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
|
|
||||||
break;
|
|
||||||
case 0x02: /* FST STi */
|
|
||||||
gen_call_function((void*)&FPU_FST,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
|
|
||||||
break;
|
|
||||||
case 0x03: /* FSTP STi*/
|
|
||||||
gen_call_function((void*)&FPU_FST,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
|
|
||||||
gen_call_function((void*)&FPU_FPOP,"");
|
|
||||||
break;
|
|
||||||
case 0x04: /* FUCOM STi */
|
|
||||||
gen_call_function((void*)&FPU_FUCOM,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
|
|
||||||
break;
|
|
||||||
case 0x05: /*FUCOMP STi */
|
|
||||||
gen_call_function((void*)&FPU_FUCOM,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
|
|
||||||
gen_call_function((void*)&FPU_FPOP,"");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 5:Unhandled group %d subfunction %d",group,sub);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
gen_releasereg(DREG(EA));
|
|
||||||
gen_releasereg(DREG(TMPB));
|
|
||||||
} else {
|
|
||||||
dyn_fill_ea();
|
|
||||||
switch(group){
|
|
||||||
case 0x00: /* FLD double real*/
|
|
||||||
gen_call_function((void*)&FPU_PREP_PUSH,"");
|
|
||||||
gen_protectflags();
|
|
||||||
gen_load_host(&TOP,DREG(TMPB),4);
|
|
||||||
gen_call_function((void*)&FPU_FLD_F64,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
|
|
||||||
break;
|
|
||||||
case 0x01: /* FISTTP longint*/
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 5 EA:Unhandled group %d subfunction %d",group,sub);
|
|
||||||
break;
|
|
||||||
case 0x02: /* FST double real*/
|
|
||||||
gen_call_function((void*)&FPU_FST_F64,"%Ddr",DREG(EA));
|
|
||||||
break;
|
|
||||||
case 0x03: /* FSTP double real*/
|
|
||||||
gen_call_function((void*)&FPU_FST_F64,"%Ddr",DREG(EA));
|
|
||||||
gen_call_function((void*)&FPU_FPOP,"");
|
|
||||||
break;
|
|
||||||
case 0x04: /* FRSTOR */
|
|
||||||
gen_call_function((void*)&FPU_FRSTOR,"%Ddr",DREG(EA));
|
|
||||||
break;
|
|
||||||
case 0x06: /* FSAVE */
|
|
||||||
gen_call_function((void*)&FPU_FSAVE,"%Ddr",DREG(EA));
|
|
||||||
break;
|
|
||||||
case 0x07: /*FNSTSW */
|
|
||||||
gen_protectflags();
|
|
||||||
gen_load_host(&TOP,DREG(TMPB),4);
|
|
||||||
gen_call_function((void*)&FPU_SET_TOP,"%Dd",DREG(TMPB));
|
|
||||||
gen_load_host(&fpu.sw,DREG(TMPB),4);
|
|
||||||
gen_call_function((void*)&mem_writew,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 5 EA:Unhandled group %d subfunction %d",group,sub);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dyn_fpu_esc6(){
|
|
||||||
dyn_get_modrm();
|
|
||||||
Bitu group=(decode.modrm.val >> 3) & 7;
|
|
||||||
Bitu sub=(decode.modrm.val & 7);
|
|
||||||
if (decode.modrm.val >= 0xc0) {
|
|
||||||
dyn_fpu_top();
|
|
||||||
switch(group){
|
|
||||||
case 0x00: /*FADDP STi,ST*/
|
|
||||||
gen_call_function((void*)&FPU_FADD,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
|
|
||||||
break;
|
|
||||||
case 0x01: /* FMULP STi,ST*/
|
|
||||||
gen_call_function((void*)&FPU_FMUL,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
|
|
||||||
break;
|
|
||||||
case 0x02: /* FCOMP5*/
|
|
||||||
gen_call_function((void*)&FPU_FCOM,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
|
|
||||||
break; /* TODO IS THIS ALLRIGHT ????????? */
|
|
||||||
case 0x03: /*FCOMPP*/
|
|
||||||
if(sub != 1) {
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 6:Unhandled group %d subfunction %d",group,sub);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
gen_load_host(&TOP,DREG(EA),4);
|
|
||||||
gen_dop_word_imm(DOP_ADD,true,DREG(EA),1);
|
|
||||||
gen_dop_word_imm(DOP_AND,true,DREG(EA),7);
|
|
||||||
gen_call_function((void*)&FPU_FCOM,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
|
|
||||||
gen_call_function((void*)&FPU_FPOP,""); /* extra pop at the bottom*/
|
|
||||||
break;
|
|
||||||
case 0x04: /* FSUBRP STi,ST*/
|
|
||||||
gen_call_function((void*)&FPU_FSUBR,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
|
|
||||||
break;
|
|
||||||
case 0x05: /* FSUBP STi,ST*/
|
|
||||||
gen_call_function((void*)&FPU_FSUB,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
|
|
||||||
break;
|
|
||||||
case 0x06: /* FDIVRP STi,ST*/
|
|
||||||
gen_call_function((void*)&FPU_FDIVR,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
|
|
||||||
break;
|
|
||||||
case 0x07: /* FDIVP STi,ST*/
|
|
||||||
gen_call_function((void*)&FPU_FDIV,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
gen_call_function((void*)&FPU_FPOP,"");
|
|
||||||
} else {
|
|
||||||
dyn_fill_ea();
|
|
||||||
gen_call_function((void*)&FPU_FLD_I16_EA,"%Ddr",DREG(EA));
|
|
||||||
gen_load_host(&TOP,DREG(TMPB),4);
|
|
||||||
dyn_eatree();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dyn_fpu_esc7(){
|
|
||||||
dyn_get_modrm();
|
|
||||||
Bitu group=(decode.modrm.val >> 3) & 7;
|
|
||||||
Bitu sub=(decode.modrm.val & 7);
|
|
||||||
if (decode.modrm.val >= 0xc0) {
|
|
||||||
switch (group){
|
|
||||||
case 0x01: /* FXCH STi*/
|
|
||||||
dyn_fpu_top();
|
|
||||||
gen_call_function((void*)&FPU_FXCH,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
|
|
||||||
break;
|
|
||||||
case 0x02: /* FSTP STi*/
|
|
||||||
case 0x03: /* FSTP STi*/
|
|
||||||
dyn_fpu_top();
|
|
||||||
gen_call_function((void*)&FPU_FST,"%Ddr%Ddr",DREG(TMPB),DREG(EA));
|
|
||||||
gen_call_function((void*)&FPU_FPOP,"");
|
|
||||||
break;
|
|
||||||
case 0x04:
|
|
||||||
switch(sub){
|
|
||||||
case 0x00: /* FNSTSW AX*/
|
|
||||||
gen_load_host(&TOP,DREG(TMPB),4);
|
|
||||||
gen_call_function((void*)&FPU_SET_TOP,"%Ddr",DREG(TMPB));
|
|
||||||
gen_mov_host(&fpu.sw,DREG(EAX),2);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",group,sub);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",group,sub);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dyn_fill_ea();
|
|
||||||
switch(group){
|
|
||||||
case 0x00: /* FILD Bit16s */
|
|
||||||
gen_call_function((void*)&FPU_PREP_PUSH,"");
|
|
||||||
gen_load_host(&TOP,DREG(TMPB),4);
|
|
||||||
gen_call_function((void*)&FPU_FLD_I16,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
|
|
||||||
break;
|
|
||||||
case 0x01:
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 7 EA:Unhandled group %d subfunction %d",group,sub);
|
|
||||||
break;
|
|
||||||
case 0x02: /* FIST Bit16s */
|
|
||||||
gen_call_function((void*)&FPU_FST_I16,"%Ddr",DREG(EA));
|
|
||||||
break;
|
|
||||||
case 0x03: /* FISTP Bit16s */
|
|
||||||
gen_call_function((void*)&FPU_FST_I16,"%Ddr",DREG(EA));
|
|
||||||
gen_call_function((void*)&FPU_FPOP,"");
|
|
||||||
break;
|
|
||||||
case 0x04: /* FBLD packed BCD */
|
|
||||||
gen_call_function((void*)&FPU_PREP_PUSH,"");
|
|
||||||
gen_load_host(&TOP,DREG(TMPB),4);
|
|
||||||
gen_call_function((void*)&FPU_FBLD,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
|
|
||||||
break;
|
|
||||||
case 0x05: /* FILD Bit64s */
|
|
||||||
gen_call_function((void*)&FPU_PREP_PUSH,"");
|
|
||||||
gen_load_host(&TOP,DREG(TMPB),4);
|
|
||||||
gen_call_function((void*)&FPU_FLD_I64,"%Ddr%Ddr",DREG(EA),DREG(TMPB));
|
|
||||||
break;
|
|
||||||
case 0x06: /* FBSTP packed BCD */
|
|
||||||
gen_call_function((void*)&FPU_FBST,"%Ddr",DREG(EA));
|
|
||||||
gen_call_function((void*)&FPU_FPOP,"");
|
|
||||||
break;
|
|
||||||
case 0x07: /* FISTP Bit64s */
|
|
||||||
gen_call_function((void*)&FPU_FST_I64,"%Ddr",DREG(EA));
|
|
||||||
gen_call_function((void*)&FPU_FPOP,"");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 7 EA:Unhandled group %d subfunction %d",group,sub);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,494 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2002-2007 The DOSBox Team
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* $Id: dyn_fpu_dh.h,v 1.5 2007/09/29 13:23:59 c2woody Exp $ */
|
|
||||||
|
|
||||||
#include "dosbox.h"
|
|
||||||
#if C_FPU
|
|
||||||
|
|
||||||
static void FPU_FLD_16(PhysPt addr) {
|
|
||||||
dyn_dh_fpu.temp.m1 = (Bit32u)mem_readw(addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void FPU_FST_16(PhysPt addr) {
|
|
||||||
mem_writew(addr,(Bit16u)dyn_dh_fpu.temp.m1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void FPU_FLD_32(PhysPt addr) {
|
|
||||||
dyn_dh_fpu.temp.m1 = mem_readd(addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void FPU_FST_32(PhysPt addr) {
|
|
||||||
mem_writed(addr,dyn_dh_fpu.temp.m1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void FPU_FLD_64(PhysPt addr) {
|
|
||||||
dyn_dh_fpu.temp.m1 = mem_readd(addr);
|
|
||||||
dyn_dh_fpu.temp.m2 = mem_readd(addr+4);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void FPU_FST_64(PhysPt addr) {
|
|
||||||
mem_writed(addr,dyn_dh_fpu.temp.m1);
|
|
||||||
mem_writed(addr+4,dyn_dh_fpu.temp.m2);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void FPU_FLD_80(PhysPt addr) {
|
|
||||||
dyn_dh_fpu.temp.m1 = mem_readd(addr);
|
|
||||||
dyn_dh_fpu.temp.m2 = mem_readd(addr+4);
|
|
||||||
dyn_dh_fpu.temp.m3 = mem_readw(addr+8);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void FPU_FST_80(PhysPt addr) {
|
|
||||||
mem_writed(addr,dyn_dh_fpu.temp.m1);
|
|
||||||
mem_writed(addr+4,dyn_dh_fpu.temp.m2);
|
|
||||||
mem_writew(addr+8,dyn_dh_fpu.temp.m3);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void FPU_FLDCW_DH(PhysPt addr){
|
|
||||||
dyn_dh_fpu.cw = mem_readw(addr);
|
|
||||||
dyn_dh_fpu.temp.m1 = (Bit32u)(dyn_dh_fpu.cw|0x3f);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void FPU_FNSTCW_DH(PhysPt addr){
|
|
||||||
mem_writew(addr,(Bit16u)(dyn_dh_fpu.cw&0xffff));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void FPU_FNINIT_DH(void){
|
|
||||||
dyn_dh_fpu.cw = 0x37f;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void FPU_FSTENV_DH(PhysPt addr){
|
|
||||||
if(!cpu.code.big) {
|
|
||||||
mem_writew(addr+0,(Bit16u)dyn_dh_fpu.cw);
|
|
||||||
mem_writew(addr+2,(Bit16u)dyn_dh_fpu.temp.m2);
|
|
||||||
mem_writew(addr+4,dyn_dh_fpu.temp.m3);
|
|
||||||
} else {
|
|
||||||
mem_writed(addr+0,dyn_dh_fpu.temp.m1);
|
|
||||||
mem_writew(addr+0,(Bit16u)dyn_dh_fpu.cw);
|
|
||||||
mem_writed(addr+4,dyn_dh_fpu.temp.m2);
|
|
||||||
mem_writed(addr+8,dyn_dh_fpu.temp.m3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void FPU_FLDENV_DH(PhysPt addr){
|
|
||||||
if(!cpu.code.big) {
|
|
||||||
dyn_dh_fpu.cw = (Bit32u)mem_readw(addr);
|
|
||||||
dyn_dh_fpu.temp.m1 = dyn_dh_fpu.cw|0x3f;
|
|
||||||
dyn_dh_fpu.temp.m2 = (Bit32u)mem_readw(addr+2);
|
|
||||||
dyn_dh_fpu.temp.m3 = mem_readw(addr+4);
|
|
||||||
} else {
|
|
||||||
dyn_dh_fpu.cw = (Bit32u)mem_readw(addr);
|
|
||||||
dyn_dh_fpu.temp.m1 = mem_readd(addr)|0x3f;
|
|
||||||
dyn_dh_fpu.temp.m2 = mem_readd(addr+4);
|
|
||||||
dyn_dh_fpu.temp.m3 = mem_readw(addr+8);
|
|
||||||
dyn_dh_fpu.temp.d1 = mem_readw(addr+10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void FPU_FSAVE_DH(PhysPt addr){
|
|
||||||
if (!cpu.code.big) {
|
|
||||||
mem_writew(addr,(Bit16u)dyn_dh_fpu.cw);
|
|
||||||
addr+=2;
|
|
||||||
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x04]);
|
|
||||||
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x05]);
|
|
||||||
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x08]);
|
|
||||||
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x09]);
|
|
||||||
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x0c]);
|
|
||||||
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x0d]);
|
|
||||||
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x10]);
|
|
||||||
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x11]);
|
|
||||||
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x14]);
|
|
||||||
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x15]);
|
|
||||||
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x18]);
|
|
||||||
mem_writeb(addr++,dyn_dh_fpu.temp_state[0x19]);
|
|
||||||
for(Bitu i=28;i<108;i++) mem_writeb(addr++,dyn_dh_fpu.temp_state[i]);
|
|
||||||
} else {
|
|
||||||
mem_writew(addr,(Bit16u)dyn_dh_fpu.cw);
|
|
||||||
addr+=2;
|
|
||||||
for(Bitu i=2;i<108;i++) mem_writeb(addr++,dyn_dh_fpu.temp_state[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void FPU_FRSTOR_DH(PhysPt addr){
|
|
||||||
if (!cpu.code.big) {
|
|
||||||
dyn_dh_fpu.cw = (Bit32u)mem_readw(addr);
|
|
||||||
dyn_dh_fpu.temp_state[0x00] = mem_readb(addr++)|0x3f;
|
|
||||||
dyn_dh_fpu.temp_state[0x01] = mem_readb(addr++);
|
|
||||||
dyn_dh_fpu.temp_state[0x04] = mem_readb(addr++);
|
|
||||||
dyn_dh_fpu.temp_state[0x05] = mem_readb(addr++);
|
|
||||||
dyn_dh_fpu.temp_state[0x08] = mem_readb(addr++);
|
|
||||||
dyn_dh_fpu.temp_state[0x09] = mem_readb(addr++);
|
|
||||||
dyn_dh_fpu.temp_state[0x0c] = mem_readb(addr++);
|
|
||||||
dyn_dh_fpu.temp_state[0x0d] = mem_readb(addr++);
|
|
||||||
dyn_dh_fpu.temp_state[0x10] = mem_readb(addr++);
|
|
||||||
dyn_dh_fpu.temp_state[0x11] = mem_readb(addr++);
|
|
||||||
dyn_dh_fpu.temp_state[0x14] = mem_readb(addr++);
|
|
||||||
dyn_dh_fpu.temp_state[0x15] = mem_readb(addr++);
|
|
||||||
dyn_dh_fpu.temp_state[0x18] = mem_readb(addr++);
|
|
||||||
dyn_dh_fpu.temp_state[0x19] = mem_readb(addr++);
|
|
||||||
for(Bitu i=28;i<108;i++) dyn_dh_fpu.temp_state[i] = mem_readb(addr++);
|
|
||||||
} else {
|
|
||||||
dyn_dh_fpu.cw = (Bit32u)mem_readw(addr);
|
|
||||||
for(Bitu i=0;i<108;i++) dyn_dh_fpu.temp_state[i] = mem_readb(addr++);
|
|
||||||
dyn_dh_fpu.temp_state[0]|=0x3f;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dh_fpu_esc0(){
|
|
||||||
dyn_get_modrm();
|
|
||||||
if (decode.modrm.val >= 0xc0) {
|
|
||||||
cache_addb(0xd8);
|
|
||||||
cache_addb(decode.modrm.val);
|
|
||||||
} else {
|
|
||||||
dyn_fill_ea();
|
|
||||||
gen_call_function((void*)&FPU_FLD_32,"%Ddr",DREG(EA));
|
|
||||||
cache_addb(0xd8);
|
|
||||||
cache_addb(0x05|(decode.modrm.reg<<3));
|
|
||||||
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dh_fpu_esc1(){
|
|
||||||
dyn_get_modrm();
|
|
||||||
if (decode.modrm.val >= 0xc0) {
|
|
||||||
cache_addb(0xd9);
|
|
||||||
cache_addb(decode.modrm.val);
|
|
||||||
} else {
|
|
||||||
Bitu group=(decode.modrm.val >> 3) & 7;
|
|
||||||
Bitu sub=(decode.modrm.val & 7);
|
|
||||||
dyn_fill_ea();
|
|
||||||
switch(group){
|
|
||||||
case 0x00: /* FLD float*/
|
|
||||||
gen_call_function((void*)&FPU_FLD_32,"%Ddr",DREG(EA));
|
|
||||||
cache_addb(0xd9);
|
|
||||||
cache_addb(0x05|(decode.modrm.reg<<3));
|
|
||||||
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
|
|
||||||
break;
|
|
||||||
case 0x01: /* UNKNOWN */
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC EA 1:Unhandled group %d subfunction %d",group,sub);
|
|
||||||
break;
|
|
||||||
case 0x02: /* FST float*/
|
|
||||||
cache_addb(0xd9);
|
|
||||||
cache_addb(0x05|(decode.modrm.reg<<3));
|
|
||||||
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
|
|
||||||
gen_call_function((void*)&FPU_FST_32,"%Ddr",DREG(EA));
|
|
||||||
break;
|
|
||||||
case 0x03: /* FSTP float*/
|
|
||||||
cache_addb(0xd9);
|
|
||||||
cache_addb(0x05|(decode.modrm.reg<<3));
|
|
||||||
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
|
|
||||||
gen_call_function((void*)&FPU_FST_32,"%Ddr",DREG(EA));
|
|
||||||
break;
|
|
||||||
case 0x04: /* FLDENV */
|
|
||||||
gen_call_function((void*)&FPU_FLDENV_DH,"%Ddr",DREG(EA));
|
|
||||||
cache_addb(0xd9);
|
|
||||||
cache_addb(0x05|(decode.modrm.reg<<3));
|
|
||||||
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
|
|
||||||
break;
|
|
||||||
case 0x05: /* FLDCW */
|
|
||||||
gen_call_function((void *)&FPU_FLDCW_DH,"%Ddr",DREG(EA));
|
|
||||||
cache_addb(0xd9);
|
|
||||||
cache_addb(0x05|(decode.modrm.reg<<3));
|
|
||||||
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
|
|
||||||
break;
|
|
||||||
case 0x06: /* FSTENV */
|
|
||||||
cache_addb(0xd9);
|
|
||||||
cache_addb(0x05|(decode.modrm.reg<<3));
|
|
||||||
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
|
|
||||||
gen_call_function((void*)&FPU_FSTENV_DH,"%Ddr",DREG(EA));
|
|
||||||
break;
|
|
||||||
case 0x07: /* FNSTCW*/
|
|
||||||
gen_call_function((void*)&FPU_FNSTCW_DH,"%Ddr",DREG(EA));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC EA 1:Unhandled group %d subfunction %d",group,sub);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dh_fpu_esc2(){
|
|
||||||
dyn_get_modrm();
|
|
||||||
if (decode.modrm.val >= 0xc0) {
|
|
||||||
cache_addb(0xda);
|
|
||||||
cache_addb(decode.modrm.val);
|
|
||||||
} else {
|
|
||||||
dyn_fill_ea();
|
|
||||||
gen_call_function((void*)&FPU_FLD_32,"%Ddr",DREG(EA));
|
|
||||||
cache_addb(0xda);
|
|
||||||
cache_addb(0x05|(decode.modrm.reg<<3));
|
|
||||||
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dh_fpu_esc3(){
|
|
||||||
dyn_get_modrm();
|
|
||||||
if (decode.modrm.val >= 0xc0) {
|
|
||||||
Bitu group=(decode.modrm.val >> 3) & 7;
|
|
||||||
Bitu sub=(decode.modrm.val & 7);
|
|
||||||
switch (group) {
|
|
||||||
case 0x04:
|
|
||||||
switch (sub) {
|
|
||||||
case 0x00: //FNENI
|
|
||||||
case 0x01: //FNDIS
|
|
||||||
LOG(LOG_FPU,LOG_ERROR)("8087 only fpu code used esc 3: group 4: subfuntion :%d",sub);
|
|
||||||
break;
|
|
||||||
case 0x02: //FNCLEX FCLEX
|
|
||||||
cache_addb(0xdb);
|
|
||||||
cache_addb(decode.modrm.val);
|
|
||||||
break;
|
|
||||||
case 0x03: //FNINIT FINIT
|
|
||||||
gen_call_function((void*)&FPU_FNINIT_DH,"");
|
|
||||||
cache_addb(0xdb);
|
|
||||||
cache_addb(decode.modrm.val);
|
|
||||||
break;
|
|
||||||
case 0x04: //FNSETPM
|
|
||||||
case 0x05: //FRSTPM
|
|
||||||
// LOG(LOG_FPU,LOG_ERROR)("80267 protected mode (un)set. Nothing done");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
E_Exit("ESC 3:ILLEGAL OPCODE group %d subfunction %d",group,sub);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 3:Unhandled group %d subfunction %d",group,sub);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Bitu group=(decode.modrm.val >> 3) & 7;
|
|
||||||
Bitu sub=(decode.modrm.val & 7);
|
|
||||||
dyn_fill_ea();
|
|
||||||
switch(group){
|
|
||||||
case 0x00: /* FILD */
|
|
||||||
gen_call_function((void*)&FPU_FLD_32,"%Ddr",DREG(EA));
|
|
||||||
cache_addb(0xdb);
|
|
||||||
cache_addb(0x05|(decode.modrm.reg<<3));
|
|
||||||
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
|
|
||||||
break;
|
|
||||||
case 0x01: /* FISTTP */
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 3 EA:Unhandled group %d subfunction %d",group,sub);
|
|
||||||
break;
|
|
||||||
case 0x02: /* FIST */
|
|
||||||
cache_addb(0xdb);
|
|
||||||
cache_addb(0x05|(decode.modrm.reg<<3));
|
|
||||||
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
|
|
||||||
gen_call_function((void*)&FPU_FST_32,"%Ddr",DREG(EA));
|
|
||||||
break;
|
|
||||||
case 0x03: /* FISTP */
|
|
||||||
cache_addb(0xdb);
|
|
||||||
cache_addb(0x05|(decode.modrm.reg<<3));
|
|
||||||
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
|
|
||||||
gen_call_function((void*)&FPU_FST_32,"%Ddr",DREG(EA));
|
|
||||||
break;
|
|
||||||
case 0x05: /* FLD 80 Bits Real */
|
|
||||||
gen_call_function((void*)&FPU_FLD_80,"%Ddr",DREG(EA));
|
|
||||||
cache_addb(0xdb);
|
|
||||||
cache_addb(0x05|(decode.modrm.reg<<3));
|
|
||||||
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
|
|
||||||
break;
|
|
||||||
case 0x07: /* FSTP 80 Bits Real */
|
|
||||||
cache_addb(0xdb);
|
|
||||||
cache_addb(0x05|(decode.modrm.reg<<3));
|
|
||||||
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
|
|
||||||
gen_call_function((void*)&FPU_FST_80,"%Ddr",DREG(EA));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 3 EA:Unhandled group %d subfunction %d",group,sub);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dh_fpu_esc4(){
|
|
||||||
dyn_get_modrm();
|
|
||||||
Bitu group=(decode.modrm.val >> 3) & 7;
|
|
||||||
Bitu sub=(decode.modrm.val & 7);
|
|
||||||
if (decode.modrm.val >= 0xc0) {
|
|
||||||
cache_addb(0xdc);
|
|
||||||
cache_addb(decode.modrm.val);
|
|
||||||
} else {
|
|
||||||
dyn_fill_ea();
|
|
||||||
gen_call_function((void*)&FPU_FLD_64,"%Ddr",DREG(EA));
|
|
||||||
cache_addb(0xdc);
|
|
||||||
cache_addb(0x05|(decode.modrm.reg<<3));
|
|
||||||
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dh_fpu_esc5(){
|
|
||||||
dyn_get_modrm();
|
|
||||||
if (decode.modrm.val >= 0xc0) {
|
|
||||||
cache_addb(0xdd);
|
|
||||||
cache_addb(decode.modrm.val);
|
|
||||||
} else {
|
|
||||||
dyn_fill_ea();
|
|
||||||
Bitu group=(decode.modrm.val >> 3) & 7;
|
|
||||||
Bitu sub=(decode.modrm.val & 7);
|
|
||||||
switch(group){
|
|
||||||
case 0x00: /* FLD double real*/
|
|
||||||
gen_call_function((void*)&FPU_FLD_64,"%Ddr",DREG(EA));
|
|
||||||
cache_addb(0xdd);
|
|
||||||
cache_addb(0x05|(decode.modrm.reg<<3));
|
|
||||||
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
|
|
||||||
break;
|
|
||||||
case 0x01: /* FISTTP longint*/
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 5 EA:Unhandled group %d subfunction %d",group,sub);
|
|
||||||
break;
|
|
||||||
case 0x02: /* FST double real*/
|
|
||||||
cache_addb(0xdd);
|
|
||||||
cache_addb(0x05|(decode.modrm.reg<<3));
|
|
||||||
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
|
|
||||||
gen_call_function((void*)&FPU_FST_64,"%Ddr",DREG(EA));
|
|
||||||
break;
|
|
||||||
case 0x03: /* FSTP double real*/
|
|
||||||
cache_addb(0xdd);
|
|
||||||
cache_addb(0x05|(decode.modrm.reg<<3));
|
|
||||||
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
|
|
||||||
gen_call_function((void*)&FPU_FST_64,"%Ddr",DREG(EA));
|
|
||||||
break;
|
|
||||||
case 0x04: /* FRSTOR */
|
|
||||||
gen_call_function((void*)&FPU_FRSTOR_DH,"%Ddr",DREG(EA));
|
|
||||||
cache_addb(0xdd);
|
|
||||||
cache_addb(0x05|(decode.modrm.reg<<3));
|
|
||||||
cache_addd((Bit32u)(&(dyn_dh_fpu.temp_state[0])));
|
|
||||||
break;
|
|
||||||
case 0x06: /* FSAVE */
|
|
||||||
cache_addb(0xdd);
|
|
||||||
cache_addb(0x05|(decode.modrm.reg<<3));
|
|
||||||
cache_addd((Bit32u)(&(dyn_dh_fpu.temp_state[0])));
|
|
||||||
gen_call_function((void*)&FPU_FSAVE_DH,"%Ddr",DREG(EA));
|
|
||||||
cache_addb(0xdb);
|
|
||||||
cache_addb(0xe3);
|
|
||||||
break;
|
|
||||||
case 0x07: /* FNSTSW */
|
|
||||||
cache_addb(0xdd);
|
|
||||||
cache_addb(0x05|(decode.modrm.reg<<3));
|
|
||||||
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
|
|
||||||
gen_call_function((void*)&FPU_FST_16,"%Ddr",DREG(EA));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 5 EA:Unhandled group %d subfunction %d",group,sub);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dh_fpu_esc6(){
|
|
||||||
dyn_get_modrm();
|
|
||||||
Bitu group=(decode.modrm.val >> 3) & 7;
|
|
||||||
Bitu sub=(decode.modrm.val & 7);
|
|
||||||
if (decode.modrm.val >= 0xc0) {
|
|
||||||
cache_addb(0xde);
|
|
||||||
cache_addb(decode.modrm.val);
|
|
||||||
} else {
|
|
||||||
dyn_fill_ea();
|
|
||||||
gen_call_function((void*)&FPU_FLD_16,"%Ddr",DREG(EA));
|
|
||||||
cache_addb(0xde);
|
|
||||||
cache_addb(0x05|(decode.modrm.reg<<3));
|
|
||||||
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dh_fpu_esc7(){
|
|
||||||
dyn_get_modrm();
|
|
||||||
Bitu group=(decode.modrm.val >> 3) & 7;
|
|
||||||
Bitu sub=(decode.modrm.val & 7);
|
|
||||||
if (decode.modrm.val >= 0xc0) {
|
|
||||||
switch (group){
|
|
||||||
case 0x01: /* FXCH STi*/
|
|
||||||
cache_addb(0xdf);
|
|
||||||
cache_addb(decode.modrm.val);
|
|
||||||
break;
|
|
||||||
case 0x02: /* FSTP STi*/
|
|
||||||
case 0x03: /* FSTP STi*/
|
|
||||||
cache_addb(0xdf);
|
|
||||||
cache_addb(decode.modrm.val);
|
|
||||||
break;
|
|
||||||
case 0x04:
|
|
||||||
switch(sub){
|
|
||||||
case 0x00: /* FNSTSW AX*/
|
|
||||||
cache_addb(0xdd);
|
|
||||||
cache_addb(0x05|(0x07<<3));
|
|
||||||
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
|
|
||||||
gen_load_host(&(dyn_dh_fpu.temp.m1),DREG(TMPB),4);
|
|
||||||
gen_dop_word(DOP_MOV,false,DREG(EAX),DREG(TMPB));
|
|
||||||
gen_releasereg(DREG(TMPB));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",group,sub);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",group,sub);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dyn_fill_ea();
|
|
||||||
switch(group){
|
|
||||||
case 0x00: /* FILD Bit16s */
|
|
||||||
gen_call_function((void*)&FPU_FLD_16,"%Ddr",DREG(EA));
|
|
||||||
cache_addb(0xdf);
|
|
||||||
cache_addb(0x05|(decode.modrm.reg<<3));
|
|
||||||
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
|
|
||||||
break;
|
|
||||||
case 0x01:
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 7 EA:Unhandled group %d subfunction %d",group,sub);
|
|
||||||
break;
|
|
||||||
case 0x02: /* FIST Bit16s */
|
|
||||||
cache_addb(0xdf);
|
|
||||||
cache_addb(0x05|(decode.modrm.reg<<3));
|
|
||||||
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
|
|
||||||
gen_call_function((void*)&FPU_FST_16,"%Ddr",DREG(EA));
|
|
||||||
break;
|
|
||||||
case 0x03: /* FISTP Bit16s */
|
|
||||||
cache_addb(0xdf);
|
|
||||||
cache_addb(0x05|(decode.modrm.reg<<3));
|
|
||||||
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
|
|
||||||
gen_call_function((void*)&FPU_FST_16,"%Ddr",DREG(EA));
|
|
||||||
break;
|
|
||||||
case 0x04: /* FBLD packed BCD */
|
|
||||||
gen_call_function((void*)&FPU_FLD_80,"%Ddr",DREG(EA));
|
|
||||||
cache_addb(0xdf);
|
|
||||||
cache_addb(0x05|(decode.modrm.reg<<3));
|
|
||||||
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
|
|
||||||
break;
|
|
||||||
case 0x05: /* FILD Bit64s */
|
|
||||||
gen_call_function((void*)&FPU_FLD_64,"%Ddr",DREG(EA));
|
|
||||||
cache_addb(0xdf);
|
|
||||||
cache_addb(0x05|(decode.modrm.reg<<3));
|
|
||||||
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
|
|
||||||
break;
|
|
||||||
case 0x06: /* FBSTP packed BCD */
|
|
||||||
cache_addb(0xdf);
|
|
||||||
cache_addb(0x05|(decode.modrm.reg<<3));
|
|
||||||
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
|
|
||||||
gen_call_function((void*)&FPU_FST_80,"%Ddr",DREG(EA));
|
|
||||||
break;
|
|
||||||
case 0x07: /* FISTP Bit64s */
|
|
||||||
cache_addb(0xdf);
|
|
||||||
cache_addb(0x05|(decode.modrm.reg<<3));
|
|
||||||
cache_addd((Bit32u)(&(dyn_dh_fpu.temp.m1)));
|
|
||||||
gen_call_function((void*)&FPU_FST_64,"%Ddr",DREG(EA));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 7 EA:Unhandled group %d subfunction %d",group,sub);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,69 +0,0 @@
|
|||||||
static bool dyn_helper_divb(Bit8u val) {
|
|
||||||
if (!val) return CPU_PrepareException(0,0);
|
|
||||||
Bitu quo=reg_ax / val;
|
|
||||||
Bit8u rem=(Bit8u)(reg_ax % val);
|
|
||||||
Bit8u quo8=(Bit8u)(quo&0xff);
|
|
||||||
if (quo>0xff) return CPU_PrepareException(0,0);
|
|
||||||
reg_ah=rem;
|
|
||||||
reg_al=quo8;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool dyn_helper_idivb(Bit8s val) {
|
|
||||||
if (!val) return CPU_PrepareException(0,0);
|
|
||||||
Bits quo=(Bit16s)reg_ax / val;
|
|
||||||
Bit8s rem=(Bit8s)((Bit16s)reg_ax % val);
|
|
||||||
Bit8s quo8s=(Bit8s)(quo&0xff);
|
|
||||||
if (quo!=(Bit16s)quo8s) return CPU_PrepareException(0,0);
|
|
||||||
reg_ah=rem;
|
|
||||||
reg_al=quo8s;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool dyn_helper_divw(Bit16u val) {
|
|
||||||
if (!val) return CPU_PrepareException(0,0);
|
|
||||||
Bitu num=(reg_dx<<16)|reg_ax;
|
|
||||||
Bitu quo=num/val;
|
|
||||||
Bit16u rem=(Bit16u)(num % val);
|
|
||||||
Bit16u quo16=(Bit16u)(quo&0xffff);
|
|
||||||
if (quo!=(Bit32u)quo16) return CPU_PrepareException(0,0);
|
|
||||||
reg_dx=rem;
|
|
||||||
reg_ax=quo16;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool dyn_helper_idivw(Bit16s val) {
|
|
||||||
if (!val) return CPU_PrepareException(0,0);
|
|
||||||
Bits num=(reg_dx<<16)|reg_ax;
|
|
||||||
Bits quo=num/val;
|
|
||||||
Bit16s rem=(Bit16s)(num % val);
|
|
||||||
Bit16s quo16s=(Bit16s)quo;
|
|
||||||
if (quo!=(Bit32s)quo16s) return CPU_PrepareException(0,0);
|
|
||||||
reg_dx=rem;
|
|
||||||
reg_ax=quo16s;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool dyn_helper_divd(Bit32u val) {
|
|
||||||
if (!val) return CPU_PrepareException(0,0);
|
|
||||||
Bit64u num=(((Bit64u)reg_edx)<<32)|reg_eax;
|
|
||||||
Bit64u quo=num/val;
|
|
||||||
Bit32u rem=(Bit32u)(num % val);
|
|
||||||
Bit32u quo32=(Bit32u)(quo&0xffffffff);
|
|
||||||
if (quo!=(Bit64u)quo32) return CPU_PrepareException(0,0);
|
|
||||||
reg_edx=rem;
|
|
||||||
reg_eax=quo32;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool dyn_helper_idivd(Bit32s val) {
|
|
||||||
if (!val) return CPU_PrepareException(0,0);
|
|
||||||
Bit64s num=(((Bit64u)reg_edx)<<32)|reg_eax;
|
|
||||||
Bit64s quo=num/val;
|
|
||||||
Bit32s rem=(Bit32s)(num % val);
|
|
||||||
Bit32s quo32s=(Bit32s)(quo&0xffffffff);
|
|
||||||
if (quo!=(Bit64s)quo32s) return CPU_PrepareException(0,0);
|
|
||||||
reg_edx=rem;
|
|
||||||
reg_eax=quo32s;
|
|
||||||
return false;
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,164 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2002-2007 The DOSBox Team
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
enum STRING_OP {
|
|
||||||
STR_OUTSB=0,STR_OUTSW,STR_OUTSD,
|
|
||||||
STR_INSB=4,STR_INSW,STR_INSD,
|
|
||||||
STR_MOVSB=8,STR_MOVSW,STR_MOVSD,
|
|
||||||
STR_LODSB=12,STR_LODSW,STR_LODSD,
|
|
||||||
STR_STOSB=16,STR_STOSW,STR_STOSD,
|
|
||||||
STR_SCASB=20,STR_SCASW,STR_SCASD,
|
|
||||||
STR_CMPSB=24,STR_CMPSW,STR_CMPSD
|
|
||||||
};
|
|
||||||
|
|
||||||
static void dyn_string(STRING_OP op) {
|
|
||||||
DynReg * si_base=decode.segprefix ? decode.segprefix : DREG(DS);
|
|
||||||
DynReg * di_base=DREG(ES);
|
|
||||||
DynReg * tmp_reg;bool usesi;bool usedi;
|
|
||||||
gen_protectflags();
|
|
||||||
if (decode.rep) {
|
|
||||||
gen_dop_word_imm(DOP_SUB,true,DREG(CYCLES),decode.cycles);
|
|
||||||
gen_releasereg(DREG(CYCLES));
|
|
||||||
decode.cycles=0;
|
|
||||||
}
|
|
||||||
/* Check what each string operation will be using */
|
|
||||||
switch (op) {
|
|
||||||
case STR_MOVSB: case STR_MOVSW: case STR_MOVSD:
|
|
||||||
case STR_CMPSB: case STR_CMPSW: case STR_CMPSD:
|
|
||||||
tmp_reg=DREG(TMPB);usesi=true;usedi=true;break;
|
|
||||||
case STR_LODSB: case STR_LODSW: case STR_LODSD:
|
|
||||||
tmp_reg=DREG(EAX);usesi=true;usedi=false;break;
|
|
||||||
case STR_OUTSB: case STR_OUTSW: case STR_OUTSD:
|
|
||||||
tmp_reg=DREG(TMPB);usesi=true;usedi=false;break;
|
|
||||||
case STR_SCASB: case STR_SCASW: case STR_SCASD:
|
|
||||||
case STR_STOSB: case STR_STOSW: case STR_STOSD:
|
|
||||||
tmp_reg=DREG(EAX);usesi=false;usedi=true;break;
|
|
||||||
case STR_INSB: case STR_INSW: case STR_INSD:
|
|
||||||
tmp_reg=DREG(TMPB);usesi=false;usedi=true;break;
|
|
||||||
default:
|
|
||||||
IllegalOption("dyn_string op");
|
|
||||||
}
|
|
||||||
gen_load_host(&cpu.direction,DREG(TMPW),4);
|
|
||||||
switch (op & 3) {
|
|
||||||
case 0:break;
|
|
||||||
case 1:gen_shift_word_imm(SHIFT_SHL,true,DREG(TMPW),1);break;
|
|
||||||
case 2:gen_shift_word_imm(SHIFT_SHL,true,DREG(TMPW),2);break;
|
|
||||||
default:
|
|
||||||
IllegalOption("dyn_string shift");
|
|
||||||
|
|
||||||
}
|
|
||||||
if (usesi) {
|
|
||||||
gen_preloadreg(DREG(ESI));
|
|
||||||
DynRegs[G_ESI].flags|=DYNFLG_CHANGED;
|
|
||||||
gen_preloadreg(si_base);
|
|
||||||
}
|
|
||||||
if (usedi) {
|
|
||||||
gen_preloadreg(DREG(EDI));
|
|
||||||
DynRegs[G_EDI].flags|=DYNFLG_CHANGED;
|
|
||||||
gen_preloadreg(di_base);
|
|
||||||
}
|
|
||||||
if (decode.rep) {
|
|
||||||
gen_preloadreg(DREG(ECX));
|
|
||||||
DynRegs[G_ECX].flags|=DYNFLG_CHANGED;
|
|
||||||
}
|
|
||||||
DynState rep_state;
|
|
||||||
dyn_savestate(&rep_state);
|
|
||||||
Bit8u * rep_start=cache.pos;
|
|
||||||
Bit8u * rep_ecx_jmp;
|
|
||||||
/* Check if ECX!=zero */
|
|
||||||
if (decode.rep) {
|
|
||||||
gen_dop_word(DOP_OR,decode.big_addr,DREG(ECX),DREG(ECX));
|
|
||||||
rep_ecx_jmp=gen_create_branch_long(BR_Z);
|
|
||||||
}
|
|
||||||
if (usesi) {
|
|
||||||
if (!decode.big_addr) {
|
|
||||||
gen_extend_word(false,DREG(EA),DREG(ESI));
|
|
||||||
gen_lea(DREG(EA),si_base,DREG(EA),0,0);
|
|
||||||
} else {
|
|
||||||
gen_lea(DREG(EA),si_base,DREG(ESI),0,0);
|
|
||||||
}
|
|
||||||
switch (op&3) {
|
|
||||||
case 0:dyn_read_byte(DREG(EA),tmp_reg,false);break;
|
|
||||||
case 1:dyn_read_word(DREG(EA),tmp_reg,false);break;
|
|
||||||
case 2:dyn_read_word(DREG(EA),tmp_reg,true);break;
|
|
||||||
}
|
|
||||||
switch (op) {
|
|
||||||
case STR_OUTSB:
|
|
||||||
gen_call_function((void*)&IO_WriteB,"%Id%Dl",DREG(EDX),tmp_reg);break;
|
|
||||||
case STR_OUTSW:
|
|
||||||
gen_call_function((void*)&IO_WriteW,"%Id%Dw",DREG(EDX),tmp_reg);break;
|
|
||||||
case STR_OUTSD:
|
|
||||||
gen_call_function((void*)&IO_WriteD,"%Id%Dd",DREG(EDX),tmp_reg);break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (usedi) {
|
|
||||||
if (!decode.big_addr) {
|
|
||||||
gen_extend_word(false,DREG(EA),DREG(EDI));
|
|
||||||
gen_lea(DREG(EA),di_base,DREG(EA),0,0);
|
|
||||||
} else {
|
|
||||||
gen_lea(DREG(EA),di_base,DREG(EDI),0,0);
|
|
||||||
}
|
|
||||||
/* Maybe something special to be done to fill the value */
|
|
||||||
switch (op) {
|
|
||||||
case STR_INSB:
|
|
||||||
gen_call_function((void*)&IO_ReadB,"%Dw%Rl",DREG(EDX),tmp_reg);
|
|
||||||
case STR_MOVSB:
|
|
||||||
case STR_STOSB:
|
|
||||||
dyn_write_byte(DREG(EA),tmp_reg,false);
|
|
||||||
break;
|
|
||||||
case STR_INSW:
|
|
||||||
gen_call_function((void*)&IO_ReadW,"%Dw%Rw",DREG(EDX),tmp_reg);
|
|
||||||
case STR_MOVSW:
|
|
||||||
case STR_STOSW:
|
|
||||||
dyn_write_word(DREG(EA),tmp_reg,false);
|
|
||||||
break;
|
|
||||||
case STR_INSD:
|
|
||||||
gen_call_function((void*)&IO_ReadD,"%Dw%Rd",DREG(EDX),tmp_reg);
|
|
||||||
case STR_MOVSD:
|
|
||||||
case STR_STOSD:
|
|
||||||
dyn_write_word(DREG(EA),tmp_reg,true);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
IllegalOption("dyn_string op");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
gen_releasereg(DREG(EA));gen_releasereg(DREG(TMPB));
|
|
||||||
|
|
||||||
/* update registers */
|
|
||||||
if (usesi) gen_dop_word(DOP_ADD,decode.big_addr,DREG(ESI),DREG(TMPW));
|
|
||||||
if (usedi) gen_dop_word(DOP_ADD,decode.big_addr,DREG(EDI),DREG(TMPW));
|
|
||||||
|
|
||||||
if (decode.rep) {
|
|
||||||
gen_sop_word(SOP_DEC,decode.big_addr,DREG(ECX));
|
|
||||||
gen_sop_word(SOP_DEC,true,DREG(CYCLES));
|
|
||||||
gen_releasereg(DREG(CYCLES));
|
|
||||||
dyn_savestate(&save_info[used_save_info].state);
|
|
||||||
save_info[used_save_info].branch_pos=gen_create_branch_long(BR_LE);
|
|
||||||
save_info[used_save_info].eip_change=decode.op_start-decode.code_start;
|
|
||||||
save_info[used_save_info].type=normal;
|
|
||||||
used_save_info++;
|
|
||||||
|
|
||||||
/* Jump back to start of ECX check */
|
|
||||||
dyn_synchstate(&rep_state);
|
|
||||||
gen_create_jump(rep_start);
|
|
||||||
|
|
||||||
dyn_loadstate(&rep_state);
|
|
||||||
gen_fill_branch_long(rep_ecx_jmp);
|
|
||||||
}
|
|
||||||
gen_releasereg(DREG(TMPW));
|
|
||||||
}
|
|
@ -1,327 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2002-2008 The DOSBox Team
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* $Id: core_dynrec.cpp,v 1.11 2008/09/19 16:48:02 c2woody Exp $ */
|
|
||||||
|
|
||||||
#include "dosbox.h"
|
|
||||||
|
|
||||||
#if (C_DYNREC)
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#if defined (WIN32)
|
|
||||||
#include <windows.h>
|
|
||||||
#include <winbase.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (C_HAVE_MPROTECT)
|
|
||||||
#include <sys/mman.h>
|
|
||||||
|
|
||||||
#include <limits.h>
|
|
||||||
#ifndef PAGESIZE
|
|
||||||
#define PAGESIZE 4096
|
|
||||||
#endif
|
|
||||||
#endif /* C_HAVE_MPROTECT */
|
|
||||||
|
|
||||||
#include "callback.h"
|
|
||||||
#include "regs.h"
|
|
||||||
#include "mem.h"
|
|
||||||
#include "cpu.h"
|
|
||||||
#include "debug.h"
|
|
||||||
#include "paging.h"
|
|
||||||
#include "inout.h"
|
|
||||||
#include "lazyflags.h"
|
|
||||||
|
|
||||||
#define CACHE_MAXSIZE (4096*2)
|
|
||||||
#define CACHE_TOTAL (1024*1024*8)
|
|
||||||
#define CACHE_PAGES (512)
|
|
||||||
#define CACHE_BLOCKS (128*1024)
|
|
||||||
#define CACHE_ALIGN (16)
|
|
||||||
#define DYN_HASH_SHIFT (4)
|
|
||||||
#define DYN_PAGE_HASH (4096>>DYN_HASH_SHIFT)
|
|
||||||
#define DYN_LINKS (16)
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
#define DYN_LOG LOG_MSG
|
|
||||||
#else
|
|
||||||
#define DYN_LOG
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if C_FPU
|
|
||||||
#define CPU_FPU 1 //Enable FPU escape instructions
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// the emulated x86 registers
|
|
||||||
#define DRC_REG_EAX 0
|
|
||||||
#define DRC_REG_ECX 1
|
|
||||||
#define DRC_REG_EDX 2
|
|
||||||
#define DRC_REG_EBX 3
|
|
||||||
#define DRC_REG_ESP 4
|
|
||||||
#define DRC_REG_EBP 5
|
|
||||||
#define DRC_REG_ESI 6
|
|
||||||
#define DRC_REG_EDI 7
|
|
||||||
|
|
||||||
// the emulated x86 segment registers
|
|
||||||
#define DRC_SEG_ES 0
|
|
||||||
#define DRC_SEG_CS 1
|
|
||||||
#define DRC_SEG_SS 2
|
|
||||||
#define DRC_SEG_DS 3
|
|
||||||
#define DRC_SEG_FS 4
|
|
||||||
#define DRC_SEG_GS 5
|
|
||||||
|
|
||||||
|
|
||||||
// access to a general register
|
|
||||||
#define DRCD_REG_VAL(reg) (&cpu_regs.regs[reg].dword)
|
|
||||||
// access to a segment register
|
|
||||||
#define DRCD_SEG_VAL(seg) (&Segs.val[seg])
|
|
||||||
// access to the physical value of a segment register/selector
|
|
||||||
#define DRCD_SEG_PHYS(seg) (&Segs.phys[seg])
|
|
||||||
|
|
||||||
// access to an 8bit general register
|
|
||||||
#define DRCD_REG_BYTE(reg,idx) (&cpu_regs.regs[reg].byte[idx])
|
|
||||||
// access to 16/32bit general registers
|
|
||||||
#define DRCD_REG_WORD(reg,dwrd) ((dwrd)?((void*)(&cpu_regs.regs[reg].dword)):((void*)(&cpu_regs.regs[reg].word)))
|
|
||||||
|
|
||||||
|
|
||||||
enum BlockReturn {
|
|
||||||
BR_Normal=0,
|
|
||||||
BR_Cycles,
|
|
||||||
BR_Link1,BR_Link2,
|
|
||||||
BR_Opcode,
|
|
||||||
#if (C_DEBUG)
|
|
||||||
BR_OpcodeFull,
|
|
||||||
#endif
|
|
||||||
BR_Iret,
|
|
||||||
BR_CallBack,
|
|
||||||
BR_SMCBlock
|
|
||||||
};
|
|
||||||
|
|
||||||
// identificator to signal self-modification of the currently executed block
|
|
||||||
#define SMC_CURRENT_BLOCK 0xffff
|
|
||||||
|
|
||||||
|
|
||||||
static void IllegalOptionDynrec(const char* msg) {
|
|
||||||
E_Exit("DynrecCore: illegal option in %s",msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct {
|
|
||||||
BlockReturn (*runcode)(Bit8u*); // points to code that can start a block
|
|
||||||
Bitu callback; // the occurred callback
|
|
||||||
Bitu readdata; // spare space used when reading from memory
|
|
||||||
Bit32u protected_regs[8]; // space to save/restore register values
|
|
||||||
} core_dynrec;
|
|
||||||
|
|
||||||
|
|
||||||
#include "core_dynrec/cache.h"
|
|
||||||
|
|
||||||
#define X86 0x01
|
|
||||||
#define X86_64 0x02
|
|
||||||
#define MIPSEL 0x03
|
|
||||||
#define ARMV4LE 0x04
|
|
||||||
|
|
||||||
#if C_TARGETCPU == X86_64
|
|
||||||
#include "core_dynrec/risc_x64.h"
|
|
||||||
#elif C_TARGETCPU == X86
|
|
||||||
#include "core_dynrec/risc_x86.h"
|
|
||||||
#elif C_TARGETCPU == MIPSEL
|
|
||||||
#include "core_dynrec/risc_mipsel32.h"
|
|
||||||
#elif C_TARGETCPU == ARMV4LE
|
|
||||||
#include "core_dynrec/risc_armv4le.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "core_dynrec/decoder.h"
|
|
||||||
|
|
||||||
CacheBlockDynRec * LinkBlocks(BlockReturn ret) {
|
|
||||||
CacheBlockDynRec * block=NULL;
|
|
||||||
// the last instruction was a control flow modifying instruction
|
|
||||||
Bitu temp_ip=SegPhys(cs)+reg_eip;
|
|
||||||
CodePageHandlerDynRec * temp_handler=(CodePageHandlerDynRec *)get_tlb_readhandler(temp_ip);
|
|
||||||
if (temp_handler->flags & PFLAG_HASCODE) {
|
|
||||||
// see if the target is an already translated block
|
|
||||||
block=temp_handler->FindCacheBlock(temp_ip & 4095);
|
|
||||||
if (!block) return NULL;
|
|
||||||
|
|
||||||
// found it, link the current block to
|
|
||||||
cache.block.running->LinkTo(ret==BR_Link2,block);
|
|
||||||
return block;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
The core tries to find the block that should be executed next.
|
|
||||||
If such a block is found, it is run, otherwise the instruction
|
|
||||||
stream starting at ip_point is translated (see decoder.h) and
|
|
||||||
makes up a new code block that will be run.
|
|
||||||
When control is returned to CPU_Core_Dynrec_Run (which might
|
|
||||||
be right after the block is run, or somewhen long after that
|
|
||||||
due to the direct cacheblock linking) the returncode decides
|
|
||||||
the next action. This might be continuing the translation and
|
|
||||||
execution process, or returning from the core etc.
|
|
||||||
*/
|
|
||||||
|
|
||||||
Bits CPU_Core_Dynrec_Run(void) {
|
|
||||||
for (;;) {
|
|
||||||
// Determine the linear address of CS:EIP
|
|
||||||
PhysPt ip_point=SegPhys(cs)+reg_eip;
|
|
||||||
#if C_HEAVY_DEBUG
|
|
||||||
if (DEBUG_HeavyIsBreakpoint()) return debugCallback;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
CodePageHandlerDynRec * chandler=0;
|
|
||||||
// see if the current page is present and contains code
|
|
||||||
if (GCC_UNLIKELY(MakeCodePage(ip_point,chandler))) {
|
|
||||||
// page not present, throw the exception
|
|
||||||
CPU_Exception(cpu.exception.which,cpu.exception.error);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// page doesn't contain code or is special
|
|
||||||
if (GCC_UNLIKELY(!chandler)) return CPU_Core_Normal_Run();
|
|
||||||
|
|
||||||
// find correct Dynamic Block to run
|
|
||||||
CacheBlockDynRec * block=chandler->FindCacheBlock(ip_point&4095);
|
|
||||||
if (!block) {
|
|
||||||
// no block found, thus translate the instruction stream
|
|
||||||
// unless the instruction is known to be modified
|
|
||||||
if (!chandler->invalidation_map || (chandler->invalidation_map[ip_point&4095]<4)) {
|
|
||||||
// translate up to 32 instructions
|
|
||||||
block=CreateCacheBlock(chandler,ip_point,32);
|
|
||||||
} else {
|
|
||||||
// let the normal core handle this instruction to avoid zero-sized blocks
|
|
||||||
Bitu old_cycles=CPU_Cycles;
|
|
||||||
CPU_Cycles=1;
|
|
||||||
Bits nc_retcode=CPU_Core_Normal_Run();
|
|
||||||
if (!nc_retcode) {
|
|
||||||
CPU_Cycles=old_cycles-1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
CPU_CycleLeft+=old_cycles;
|
|
||||||
return nc_retcode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
run_block:
|
|
||||||
cache.block.running=0;
|
|
||||||
// now we're ready to run the dynamic code block
|
|
||||||
// BlockReturn ret=((BlockReturn (*)(void))(block->cache.start))();
|
|
||||||
BlockReturn ret=core_dynrec.runcode(block->cache.start);
|
|
||||||
|
|
||||||
switch (ret) {
|
|
||||||
case BR_Iret:
|
|
||||||
#if C_HEAVY_DEBUG
|
|
||||||
if (DEBUG_HeavyIsBreakpoint()) return debugCallback;
|
|
||||||
#endif
|
|
||||||
if (!GETFLAG(TF)) break;
|
|
||||||
// trapflag is set, switch to the trap-aware decoder
|
|
||||||
cpudecoder=CPU_Core_Dynrec_Trap_Run;
|
|
||||||
return CBRET_NONE;
|
|
||||||
|
|
||||||
case BR_Normal:
|
|
||||||
// the block was exited due to a non-predictable control flow
|
|
||||||
// modifying instruction (like ret) or some nontrivial cpu state
|
|
||||||
// changing instruction (for example switch to/from pmode),
|
|
||||||
// or the maximal number of instructions to translate was reached
|
|
||||||
#if C_HEAVY_DEBUG
|
|
||||||
if (DEBUG_HeavyIsBreakpoint()) return debugCallback;
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
|
|
||||||
case BR_Cycles:
|
|
||||||
// cycles went negative, return from the core to handle
|
|
||||||
// external events, schedule the pic...
|
|
||||||
#if C_HEAVY_DEBUG
|
|
||||||
if (DEBUG_HeavyIsBreakpoint()) return debugCallback;
|
|
||||||
#endif
|
|
||||||
return CBRET_NONE;
|
|
||||||
|
|
||||||
case BR_CallBack:
|
|
||||||
// the callback code is executed in dosbox.conf, return the callback number
|
|
||||||
FillFlags();
|
|
||||||
return core_dynrec.callback;
|
|
||||||
|
|
||||||
case BR_SMCBlock:
|
|
||||||
// LOG_MSG("selfmodification of running block at %x:%x",SegValue(cs),reg_eip);
|
|
||||||
cpu.exception.which=0;
|
|
||||||
// fallthrough, let the normal core handle the block-modifying instruction
|
|
||||||
case BR_Opcode:
|
|
||||||
// some instruction has been encountered that could not be translated
|
|
||||||
// (thus it is not part of the code block), the normal core will
|
|
||||||
// handle this instruction
|
|
||||||
CPU_CycleLeft+=CPU_Cycles;
|
|
||||||
CPU_Cycles=1;
|
|
||||||
return CPU_Core_Normal_Run();
|
|
||||||
|
|
||||||
#if (C_DEBUG)
|
|
||||||
case BR_OpcodeFull:
|
|
||||||
CPU_CycleLeft+=CPU_Cycles;
|
|
||||||
CPU_Cycles=1;
|
|
||||||
return CPU_Core_Full_Run();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
case BR_Link1:
|
|
||||||
case BR_Link2:
|
|
||||||
block=LinkBlocks(ret);
|
|
||||||
if (block) goto run_block;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
E_Exit("Invalid return code %d", ret);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return CBRET_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
Bits CPU_Core_Dynrec_Trap_Run(void) {
|
|
||||||
Bits oldCycles = CPU_Cycles;
|
|
||||||
CPU_Cycles = 1;
|
|
||||||
cpu.trap_skip = false;
|
|
||||||
|
|
||||||
// let the normal core execute the next (only one!) instruction
|
|
||||||
Bits ret=CPU_Core_Normal_Run();
|
|
||||||
|
|
||||||
// trap to int1 unless the last instruction deferred this
|
|
||||||
// (allows hardware interrupts to be served without interaction)
|
|
||||||
if (!cpu.trap_skip) CPU_HW_Interrupt(1);
|
|
||||||
|
|
||||||
CPU_Cycles = oldCycles-1;
|
|
||||||
// continue (either the trapflag was clear anyways, or the int1 cleared it)
|
|
||||||
cpudecoder = &CPU_Core_Dynrec_Run;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CPU_Core_Dynrec_Init(void) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void CPU_Core_Dynrec_Cache_Init(bool enable_cache) {
|
|
||||||
// Initialize code cache and dynamic blocks
|
|
||||||
cache_init(enable_cache);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CPU_Core_Dynrec_Cache_Close(void) {
|
|
||||||
cache_close();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,5 +0,0 @@
|
|||||||
noinst_HEADERS = cache.h decoder.h decoder_basic.h decoder_opcodes.h \
|
|
||||||
dyn_fpu.h operators.h risc_x64.h risc_x86.h risc_mipsel32.h \
|
|
||||||
risc_armv4le.h risc_armv4le-common.h \
|
|
||||||
risc_armv4le-s3.h risc_armv4le-o3.h risc_armv4le-thumb.h \
|
|
||||||
risc_armv4le-thumb-iw.h risc_armv4le-thumb-niw.h
|
|
@ -1,665 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2002-2007 The DOSBox Team
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
class CodePageHandlerDynRec; // forward
|
|
||||||
|
|
||||||
// basic cache block representation
|
|
||||||
class CacheBlockDynRec {
|
|
||||||
public:
|
|
||||||
void Clear(void);
|
|
||||||
// link this cache block to another block, index specifies the code
|
|
||||||
// path (always zero for unconditional links, 0/1 for conditional ones
|
|
||||||
void LinkTo(Bitu index,CacheBlockDynRec * toblock) {
|
|
||||||
assert(toblock);
|
|
||||||
link[index].to=toblock;
|
|
||||||
link[index].next=toblock->link[index].from; // set target block
|
|
||||||
toblock->link[index].from=this; // remember who links me
|
|
||||||
}
|
|
||||||
struct {
|
|
||||||
Bit16u start,end; // where in the page is the original code
|
|
||||||
CodePageHandlerDynRec * handler; // page containing this code
|
|
||||||
} page;
|
|
||||||
struct {
|
|
||||||
Bit8u * start; // where in the cache are we
|
|
||||||
Bitu size;
|
|
||||||
CacheBlockDynRec * next;
|
|
||||||
// writemap masking maskpointer/start/length
|
|
||||||
// to allow holes in the writemap
|
|
||||||
Bit8u * wmapmask;
|
|
||||||
Bit16u maskstart;
|
|
||||||
Bit16u masklen;
|
|
||||||
} cache;
|
|
||||||
struct {
|
|
||||||
Bitu index;
|
|
||||||
CacheBlockDynRec * next;
|
|
||||||
} hash;
|
|
||||||
struct {
|
|
||||||
CacheBlockDynRec * to; // this block can transfer control to the to-block
|
|
||||||
CacheBlockDynRec * next;
|
|
||||||
CacheBlockDynRec * from; // the from-block can transfer control to this block
|
|
||||||
} link[2]; // maximal two links (conditional jumps)
|
|
||||||
CacheBlockDynRec * crossblock;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct {
|
|
||||||
struct {
|
|
||||||
CacheBlockDynRec * first; // the first cache block in the list
|
|
||||||
CacheBlockDynRec * active; // the current cache block
|
|
||||||
CacheBlockDynRec * free; // pointer to the free list
|
|
||||||
CacheBlockDynRec * running; // the last block that was entered for execution
|
|
||||||
} block;
|
|
||||||
Bit8u * pos; // position in the cache block
|
|
||||||
CodePageHandlerDynRec * free_pages; // pointer to the free list
|
|
||||||
CodePageHandlerDynRec * used_pages; // pointer to the list of used pages
|
|
||||||
CodePageHandlerDynRec * last_page; // the last used page
|
|
||||||
} cache;
|
|
||||||
|
|
||||||
|
|
||||||
// cache memory pointers, to be malloc'd later
|
|
||||||
static Bit8u * cache_code_start_ptr=NULL;
|
|
||||||
static Bit8u * cache_code=NULL;
|
|
||||||
static Bit8u * cache_code_link_blocks=NULL;
|
|
||||||
|
|
||||||
static CacheBlockDynRec * cache_blocks=NULL;
|
|
||||||
static CacheBlockDynRec link_blocks[2]; // default linking (specially marked)
|
|
||||||
|
|
||||||
|
|
||||||
// the CodePageHandlerDynRec class provides access to the contained
|
|
||||||
// cache blocks and intercepts writes to the code for special treatment
|
|
||||||
class CodePageHandlerDynRec : public PageHandler {
|
|
||||||
public:
|
|
||||||
CodePageHandlerDynRec() {
|
|
||||||
invalidation_map=NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetupAt(Bitu _phys_page,PageHandler * _old_pagehandler) {
|
|
||||||
// initialize this codepage handler
|
|
||||||
phys_page=_phys_page;
|
|
||||||
// save the old pagehandler to provide direct read access to the memory,
|
|
||||||
// and to be able to restore it later on
|
|
||||||
old_pagehandler=_old_pagehandler;
|
|
||||||
|
|
||||||
// adjust flags
|
|
||||||
flags=old_pagehandler->flags|PFLAG_HASCODE;
|
|
||||||
flags&=~PFLAG_WRITEABLE;
|
|
||||||
|
|
||||||
active_blocks=0;
|
|
||||||
active_count=16;
|
|
||||||
|
|
||||||
// initialize the maps with zero (no cache blocks as well as code present)
|
|
||||||
memset(&hash_map,0,sizeof(hash_map));
|
|
||||||
memset(&write_map,0,sizeof(write_map));
|
|
||||||
if (invalidation_map!=NULL) {
|
|
||||||
free(invalidation_map);
|
|
||||||
invalidation_map=NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// clear out blocks that contain code which has been modified
|
|
||||||
bool InvalidateRange(Bitu start,Bitu end) {
|
|
||||||
Bits index=1+(end>>DYN_HASH_SHIFT);
|
|
||||||
bool is_current_block=false; // if the current block is modified, it has to be exited as soon as possible
|
|
||||||
|
|
||||||
Bit32u ip_point=SegPhys(cs)+reg_eip;
|
|
||||||
ip_point=(PAGING_GetPhysicalPage(ip_point)-(phys_page<<12))+(ip_point&0xfff);
|
|
||||||
while (index>=0) {
|
|
||||||
Bitu map=0;
|
|
||||||
// see if there is still some code in the range
|
|
||||||
for (Bitu count=start;count<=end;count++) map+=write_map[count];
|
|
||||||
if (!map) return is_current_block; // no more code, finished
|
|
||||||
|
|
||||||
CacheBlockDynRec * block=hash_map[index];
|
|
||||||
while (block) {
|
|
||||||
CacheBlockDynRec * nextblock=block->hash.next;
|
|
||||||
// test if this block is in the range
|
|
||||||
if (start<=block->page.end && end>=block->page.start) {
|
|
||||||
if (ip_point<=block->page.end && ip_point>=block->page.start) is_current_block=true;
|
|
||||||
block->Clear(); // clear the block, decrements the write_map accordingly
|
|
||||||
}
|
|
||||||
block=nextblock;
|
|
||||||
}
|
|
||||||
index--;
|
|
||||||
}
|
|
||||||
return is_current_block;
|
|
||||||
}
|
|
||||||
|
|
||||||
// the following functions will clean all cache blocks that are invalid now due to the write
|
|
||||||
void writeb(PhysPt addr,Bitu val){
|
|
||||||
addr&=4095;
|
|
||||||
if (host_readb(hostmem+addr)==(Bit8u)val) return;
|
|
||||||
host_writeb(hostmem+addr,val);
|
|
||||||
// see if there's code where we are writing to
|
|
||||||
if (!host_readb(&write_map[addr])) {
|
|
||||||
if (active_blocks) return; // still some blocks in this page
|
|
||||||
active_count--;
|
|
||||||
if (!active_count) Release(); // delay page releasing until active_count is zero
|
|
||||||
return;
|
|
||||||
} else if (!invalidation_map) {
|
|
||||||
invalidation_map=(Bit8u*)malloc(4096);
|
|
||||||
memset(invalidation_map,0,4096);
|
|
||||||
}
|
|
||||||
invalidation_map[addr]++;
|
|
||||||
InvalidateRange(addr,addr);
|
|
||||||
}
|
|
||||||
void writew(PhysPt addr,Bitu val){
|
|
||||||
addr&=4095;
|
|
||||||
if (host_readw(hostmem+addr)==(Bit16u)val) return;
|
|
||||||
host_writew(hostmem+addr,val);
|
|
||||||
// see if there's code where we are writing to
|
|
||||||
if (!host_readw(&write_map[addr])) {
|
|
||||||
if (active_blocks) return; // still some blocks in this page
|
|
||||||
active_count--;
|
|
||||||
if (!active_count) Release(); // delay page releasing until active_count is zero
|
|
||||||
return;
|
|
||||||
} else if (!invalidation_map) {
|
|
||||||
invalidation_map=(Bit8u*)malloc(4096);
|
|
||||||
memset(invalidation_map,0,4096);
|
|
||||||
}
|
|
||||||
#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY)
|
|
||||||
host_writew(&invalidation_map[addr],
|
|
||||||
host_readw(&invalidation_map[addr])+0x101);
|
|
||||||
#else
|
|
||||||
(*(Bit16u*)&invalidation_map[addr])+=0x101;
|
|
||||||
#endif
|
|
||||||
InvalidateRange(addr,addr+1);
|
|
||||||
}
|
|
||||||
void writed(PhysPt addr,Bitu val){
|
|
||||||
addr&=4095;
|
|
||||||
if (host_readd(hostmem+addr)==(Bit32u)val) return;
|
|
||||||
host_writed(hostmem+addr,val);
|
|
||||||
// see if there's code where we are writing to
|
|
||||||
if (!host_readd(&write_map[addr])) {
|
|
||||||
if (active_blocks) return; // still some blocks in this page
|
|
||||||
active_count--;
|
|
||||||
if (!active_count) Release(); // delay page releasing until active_count is zero
|
|
||||||
return;
|
|
||||||
} else if (!invalidation_map) {
|
|
||||||
invalidation_map=(Bit8u*)malloc(4096);
|
|
||||||
memset(invalidation_map,0,4096);
|
|
||||||
}
|
|
||||||
#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY)
|
|
||||||
host_writed(&invalidation_map[addr],
|
|
||||||
host_readd(&invalidation_map[addr])+0x1010101);
|
|
||||||
#else
|
|
||||||
(*(Bit32u*)&invalidation_map[addr])+=0x1010101;
|
|
||||||
#endif
|
|
||||||
InvalidateRange(addr,addr+3);
|
|
||||||
}
|
|
||||||
bool writeb_checked(PhysPt addr,Bitu val) {
|
|
||||||
addr&=4095;
|
|
||||||
if (host_readb(hostmem+addr)==(Bit8u)val) return false;
|
|
||||||
// see if there's code where we are writing to
|
|
||||||
if (!host_readb(&write_map[addr])) {
|
|
||||||
if (!active_blocks) {
|
|
||||||
// no blocks left in this page, still delay the page releasing a bit
|
|
||||||
active_count--;
|
|
||||||
if (!active_count) Release();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!invalidation_map) {
|
|
||||||
invalidation_map=(Bit8u*)malloc(4096);
|
|
||||||
memset(invalidation_map,0,4096);
|
|
||||||
}
|
|
||||||
invalidation_map[addr]++;
|
|
||||||
if (InvalidateRange(addr,addr)) {
|
|
||||||
cpu.exception.which=SMC_CURRENT_BLOCK;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
host_writeb(hostmem+addr,val);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool writew_checked(PhysPt addr,Bitu val) {
|
|
||||||
addr&=4095;
|
|
||||||
if (host_readw(hostmem+addr)==(Bit16u)val) return false;
|
|
||||||
// see if there's code where we are writing to
|
|
||||||
if (!host_readw(&write_map[addr])) {
|
|
||||||
if (!active_blocks) {
|
|
||||||
// no blocks left in this page, still delay the page releasing a bit
|
|
||||||
active_count--;
|
|
||||||
if (!active_count) Release();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!invalidation_map) {
|
|
||||||
invalidation_map=(Bit8u*)malloc(4096);
|
|
||||||
memset(invalidation_map,0,4096);
|
|
||||||
}
|
|
||||||
#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY)
|
|
||||||
host_writew(&invalidation_map[addr],
|
|
||||||
host_readw(&invalidation_map[addr])+0x101);
|
|
||||||
#else
|
|
||||||
(*(Bit16u*)&invalidation_map[addr])+=0x101;
|
|
||||||
#endif
|
|
||||||
if (InvalidateRange(addr,addr+1)) {
|
|
||||||
cpu.exception.which=SMC_CURRENT_BLOCK;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
host_writew(hostmem+addr,val);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
bool writed_checked(PhysPt addr,Bitu val) {
|
|
||||||
addr&=4095;
|
|
||||||
if (host_readd(hostmem+addr)==(Bit32u)val) return false;
|
|
||||||
// see if there's code where we are writing to
|
|
||||||
if (!host_readd(&write_map[addr])) {
|
|
||||||
if (!active_blocks) {
|
|
||||||
// no blocks left in this page, still delay the page releasing a bit
|
|
||||||
active_count--;
|
|
||||||
if (!active_count) Release();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!invalidation_map) {
|
|
||||||
invalidation_map=(Bit8u*)malloc(4096);
|
|
||||||
memset(invalidation_map,0,4096);
|
|
||||||
}
|
|
||||||
#if defined(WORDS_BIGENDIAN) || !defined(C_UNALIGNED_MEMORY)
|
|
||||||
host_writed(&invalidation_map[addr],
|
|
||||||
host_readd(&invalidation_map[addr])+0x1010101);
|
|
||||||
#else
|
|
||||||
(*(Bit32u*)&invalidation_map[addr])+=0x1010101;
|
|
||||||
#endif
|
|
||||||
if (InvalidateRange(addr,addr+3)) {
|
|
||||||
cpu.exception.which=SMC_CURRENT_BLOCK;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
host_writed(hostmem+addr,val);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// add a cache block to this page and note it in the hash map
|
|
||||||
void AddCacheBlock(CacheBlockDynRec * block) {
|
|
||||||
Bitu index=1+(block->page.start>>DYN_HASH_SHIFT);
|
|
||||||
block->hash.next=hash_map[index]; // link to old block at index from the new block
|
|
||||||
block->hash.index=index;
|
|
||||||
hash_map[index]=block; // put new block at hash position
|
|
||||||
block->page.handler=this;
|
|
||||||
active_blocks++;
|
|
||||||
}
|
|
||||||
// there's a block whose code started in a different page
|
|
||||||
void AddCrossBlock(CacheBlockDynRec * block) {
|
|
||||||
block->hash.next=hash_map[0];
|
|
||||||
block->hash.index=0;
|
|
||||||
hash_map[0]=block;
|
|
||||||
block->page.handler=this;
|
|
||||||
active_blocks++;
|
|
||||||
}
|
|
||||||
// remove a cache block
|
|
||||||
void DelCacheBlock(CacheBlockDynRec * block) {
|
|
||||||
active_blocks--;
|
|
||||||
active_count=16;
|
|
||||||
CacheBlockDynRec * * bwhere=&hash_map[block->hash.index];
|
|
||||||
while (*bwhere!=block) {
|
|
||||||
bwhere=&((*bwhere)->hash.next);
|
|
||||||
//Will crash if a block isn't found, which should never happen.
|
|
||||||
}
|
|
||||||
*bwhere=block->hash.next;
|
|
||||||
|
|
||||||
// remove the cleared block from the write map
|
|
||||||
if (GCC_UNLIKELY(block->cache.wmapmask!=NULL)) {
|
|
||||||
// first part is not influenced by the mask
|
|
||||||
for (Bitu i=block->page.start;i<block->cache.maskstart;i++) {
|
|
||||||
if (write_map[i]) write_map[i]--;
|
|
||||||
}
|
|
||||||
Bitu maskct=0;
|
|
||||||
// last part sticks to the writemap mask
|
|
||||||
for (Bitu i=block->cache.maskstart;i<=block->page.end;i++,maskct++) {
|
|
||||||
if (write_map[i]) {
|
|
||||||
// only adjust writemap if it isn't masked
|
|
||||||
if ((maskct>=block->cache.masklen) || (!block->cache.wmapmask[maskct])) write_map[i]--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(block->cache.wmapmask);
|
|
||||||
block->cache.wmapmask=NULL;
|
|
||||||
} else {
|
|
||||||
for (Bitu i=block->page.start;i<=block->page.end;i++) {
|
|
||||||
if (write_map[i]) write_map[i]--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Release(void) {
|
|
||||||
MEM_SetPageHandler(phys_page,1,old_pagehandler); // revert to old handler
|
|
||||||
PAGING_ClearTLB();
|
|
||||||
|
|
||||||
// remove page from the lists
|
|
||||||
if (prev) prev->next=next;
|
|
||||||
else cache.used_pages=next;
|
|
||||||
if (next) next->prev=prev;
|
|
||||||
else cache.last_page=prev;
|
|
||||||
next=cache.free_pages;
|
|
||||||
cache.free_pages=this;
|
|
||||||
prev=0;
|
|
||||||
}
|
|
||||||
void ClearRelease(void) {
|
|
||||||
// clear out all cache blocks in this page
|
|
||||||
for (Bitu index=0;index<(1+DYN_PAGE_HASH);index++) {
|
|
||||||
CacheBlockDynRec * block=hash_map[index];
|
|
||||||
while (block) {
|
|
||||||
CacheBlockDynRec * nextblock=block->hash.next;
|
|
||||||
block->page.handler=0; // no need, full clear
|
|
||||||
block->Clear();
|
|
||||||
block=nextblock;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Release(); // now can release this page
|
|
||||||
}
|
|
||||||
|
|
||||||
CacheBlockDynRec * FindCacheBlock(Bitu start) {
|
|
||||||
CacheBlockDynRec * block=hash_map[1+(start>>DYN_HASH_SHIFT)];
|
|
||||||
// see if there's a cache block present at the start address
|
|
||||||
while (block) {
|
|
||||||
if (block->page.start==start) return block; // found
|
|
||||||
block=block->hash.next;
|
|
||||||
}
|
|
||||||
return 0; // none found
|
|
||||||
}
|
|
||||||
|
|
||||||
HostPt GetHostReadPt(Bitu phys_page) {
|
|
||||||
hostmem=old_pagehandler->GetHostReadPt(phys_page);
|
|
||||||
return hostmem;
|
|
||||||
}
|
|
||||||
HostPt GetHostWritePt(Bitu phys_page) {
|
|
||||||
return GetHostReadPt( phys_page );
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
// the write map, there are write_map[i] cache blocks that cover the byte at address i
|
|
||||||
Bit8u write_map[4096];
|
|
||||||
Bit8u * invalidation_map;
|
|
||||||
CodePageHandlerDynRec * next, * prev; // page linking
|
|
||||||
private:
|
|
||||||
PageHandler * old_pagehandler;
|
|
||||||
|
|
||||||
// hash map to quickly find the cache blocks in this page
|
|
||||||
CacheBlockDynRec * hash_map[1+DYN_PAGE_HASH];
|
|
||||||
|
|
||||||
Bitu active_blocks; // the number of cache blocks in this page
|
|
||||||
Bitu active_count; // delaying parameter to not immediately release a page
|
|
||||||
HostPt hostmem;
|
|
||||||
Bitu phys_page;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE void cache_addunusedblock(CacheBlockDynRec * block) {
|
|
||||||
// block has become unused, add it to the freelist
|
|
||||||
block->cache.next=cache.block.free;
|
|
||||||
cache.block.free=block;
|
|
||||||
}
|
|
||||||
|
|
||||||
static CacheBlockDynRec * cache_getblock(void) {
|
|
||||||
// get a free cache block and advance the free pointer
|
|
||||||
CacheBlockDynRec * ret=cache.block.free;
|
|
||||||
if (!ret) E_Exit("Ran out of CacheBlocks" );
|
|
||||||
cache.block.free=ret->cache.next;
|
|
||||||
ret->cache.next=0;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CacheBlockDynRec::Clear(void) {
|
|
||||||
Bitu ind;
|
|
||||||
// check if this is not a cross page block
|
|
||||||
if (hash.index) for (ind=0;ind<2;ind++) {
|
|
||||||
CacheBlockDynRec * fromlink=link[ind].from;
|
|
||||||
link[ind].from=0;
|
|
||||||
while (fromlink) {
|
|
||||||
CacheBlockDynRec * nextlink=fromlink->link[ind].next;
|
|
||||||
// clear the next-link and let the block point to the standard linkcode
|
|
||||||
fromlink->link[ind].next=0;
|
|
||||||
fromlink->link[ind].to=&link_blocks[ind];
|
|
||||||
|
|
||||||
fromlink=nextlink;
|
|
||||||
}
|
|
||||||
if (link[ind].to!=&link_blocks[ind]) {
|
|
||||||
// not linked to the standard linkcode, find the block that links to this block
|
|
||||||
CacheBlockDynRec * * wherelink=&link[ind].to->link[ind].from;
|
|
||||||
while (*wherelink != this && *wherelink) {
|
|
||||||
wherelink = &(*wherelink)->link[ind].next;
|
|
||||||
}
|
|
||||||
// now remove the link
|
|
||||||
if(*wherelink)
|
|
||||||
*wherelink = (*wherelink)->link[ind].next;
|
|
||||||
else {
|
|
||||||
LOG(LOG_CPU,LOG_ERROR)("Cache anomaly. please investigate");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
cache_addunusedblock(this);
|
|
||||||
if (crossblock) {
|
|
||||||
// clear out the crossblock (in the page before) as well
|
|
||||||
crossblock->crossblock=0;
|
|
||||||
crossblock->Clear();
|
|
||||||
crossblock=0;
|
|
||||||
}
|
|
||||||
if (page.handler) {
|
|
||||||
// clear out the code page handler
|
|
||||||
page.handler->DelCacheBlock(this);
|
|
||||||
page.handler=0;
|
|
||||||
}
|
|
||||||
if (cache.wmapmask){
|
|
||||||
free(cache.wmapmask);
|
|
||||||
cache.wmapmask=NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static CacheBlockDynRec * cache_openblock(void) {
|
|
||||||
CacheBlockDynRec * block=cache.block.active;
|
|
||||||
// check for enough space in this block
|
|
||||||
Bitu size=block->cache.size;
|
|
||||||
CacheBlockDynRec * nextblock=block->cache.next;
|
|
||||||
if (block->page.handler)
|
|
||||||
block->Clear();
|
|
||||||
// block size must be at least CACHE_MAXSIZE
|
|
||||||
while (size<CACHE_MAXSIZE) {
|
|
||||||
if (!nextblock)
|
|
||||||
goto skipresize;
|
|
||||||
// merge blocks
|
|
||||||
size+=nextblock->cache.size;
|
|
||||||
CacheBlockDynRec * tempblock=nextblock->cache.next;
|
|
||||||
if (nextblock->page.handler)
|
|
||||||
nextblock->Clear();
|
|
||||||
// block is free now
|
|
||||||
cache_addunusedblock(nextblock);
|
|
||||||
nextblock=tempblock;
|
|
||||||
}
|
|
||||||
skipresize:
|
|
||||||
// adjust parameters and open this block
|
|
||||||
block->cache.size=size;
|
|
||||||
block->cache.next=nextblock;
|
|
||||||
cache.pos=block->cache.start;
|
|
||||||
return block;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cache_closeblock(void) {
|
|
||||||
CacheBlockDynRec * block=cache.block.active;
|
|
||||||
// links point to the default linking code
|
|
||||||
block->link[0].to=&link_blocks[0];
|
|
||||||
block->link[1].to=&link_blocks[1];
|
|
||||||
block->link[0].from=0;
|
|
||||||
block->link[1].from=0;
|
|
||||||
block->link[0].next=0;
|
|
||||||
block->link[1].next=0;
|
|
||||||
// close the block with correct alignment
|
|
||||||
Bitu written=(Bitu)(cache.pos-block->cache.start);
|
|
||||||
if (written>block->cache.size) {
|
|
||||||
if (!block->cache.next) {
|
|
||||||
if (written>block->cache.size+CACHE_MAXSIZE) E_Exit("CacheBlock overrun 1 %d",written-block->cache.size);
|
|
||||||
} else E_Exit("CacheBlock overrun 2 written %d size %d",written,block->cache.size);
|
|
||||||
} else {
|
|
||||||
Bitu new_size;
|
|
||||||
Bitu left=block->cache.size-written;
|
|
||||||
// smaller than cache align then don't bother to resize
|
|
||||||
if (left>CACHE_ALIGN) {
|
|
||||||
new_size=((written-1)|(CACHE_ALIGN-1))+1;
|
|
||||||
CacheBlockDynRec * newblock=cache_getblock();
|
|
||||||
// align block now to CACHE_ALIGN
|
|
||||||
newblock->cache.start=block->cache.start+new_size;
|
|
||||||
newblock->cache.size=block->cache.size-new_size;
|
|
||||||
newblock->cache.next=block->cache.next;
|
|
||||||
block->cache.next=newblock;
|
|
||||||
block->cache.size=new_size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// advance the active block pointer
|
|
||||||
if (!block->cache.next || (block->cache.next->cache.start>(cache_code_start_ptr + CACHE_TOTAL - CACHE_MAXSIZE))) {
|
|
||||||
// LOG_MSG("Cache full restarting");
|
|
||||||
cache.block.active=cache.block.first;
|
|
||||||
} else {
|
|
||||||
cache.block.active=block->cache.next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// place an 8bit value into the cache
|
|
||||||
static INLINE void cache_addb(Bit8u val) {
|
|
||||||
*cache.pos++=val;
|
|
||||||
}
|
|
||||||
|
|
||||||
// place a 16bit value into the cache
|
|
||||||
static INLINE void cache_addw(Bit16u val) {
|
|
||||||
*(Bit16u*)cache.pos=val;
|
|
||||||
cache.pos+=2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// place a 32bit value into the cache
|
|
||||||
static INLINE void cache_addd(Bit32u val) {
|
|
||||||
*(Bit32u*)cache.pos=val;
|
|
||||||
cache.pos+=4;
|
|
||||||
}
|
|
||||||
|
|
||||||
// place a 64bit value into the cache
|
|
||||||
static INLINE void cache_addq(Bit64u val) {
|
|
||||||
*(Bit64u*)cache.pos=val;
|
|
||||||
cache.pos+=8;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void dyn_return(BlockReturn retcode,bool ret_exception);
|
|
||||||
static void dyn_run_code(void);
|
|
||||||
|
|
||||||
|
|
||||||
/* Define temporary pagesize so the MPROTECT case and the regular case share as much code as possible */
|
|
||||||
#if (C_HAVE_MPROTECT)
|
|
||||||
#define PAGESIZE_TEMP PAGESIZE
|
|
||||||
#else
|
|
||||||
#define PAGESIZE_TEMP 4096
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static bool cache_initialized = false;
|
|
||||||
|
|
||||||
static void cache_init(bool enable) {
|
|
||||||
Bits i;
|
|
||||||
if (enable) {
|
|
||||||
// see if cache is already initialized
|
|
||||||
if (cache_initialized) return;
|
|
||||||
cache_initialized = true;
|
|
||||||
if (cache_blocks == NULL) {
|
|
||||||
// allocate the cache blocks memory
|
|
||||||
cache_blocks=(CacheBlockDynRec*)malloc(CACHE_BLOCKS*sizeof(CacheBlockDynRec));
|
|
||||||
if(!cache_blocks) E_Exit("Allocating cache_blocks has failed");
|
|
||||||
memset(cache_blocks,0,sizeof(CacheBlockDynRec)*CACHE_BLOCKS);
|
|
||||||
cache.block.free=&cache_blocks[0];
|
|
||||||
// initialize the cache blocks
|
|
||||||
for (i=0;i<CACHE_BLOCKS-1;i++) {
|
|
||||||
cache_blocks[i].link[0].to=(CacheBlockDynRec *)1;
|
|
||||||
cache_blocks[i].link[1].to=(CacheBlockDynRec *)1;
|
|
||||||
cache_blocks[i].cache.next=&cache_blocks[i+1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (cache_code_start_ptr==NULL) {
|
|
||||||
// allocate the code cache memory
|
|
||||||
#if defined (WIN32)
|
|
||||||
cache_code_start_ptr=(Bit8u*)VirtualAlloc(0,CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP-1+PAGESIZE_TEMP,
|
|
||||||
MEM_COMMIT,PAGE_EXECUTE_READWRITE);
|
|
||||||
if (!cache_code_start_ptr)
|
|
||||||
cache_code_start_ptr=(Bit8u*)malloc(CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP-1+PAGESIZE_TEMP);
|
|
||||||
#else
|
|
||||||
cache_code_start_ptr=(Bit8u*)malloc(CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP-1+PAGESIZE_TEMP);
|
|
||||||
#endif
|
|
||||||
if(!cache_code_start_ptr) E_Exit("Allocating dynamic cache failed");
|
|
||||||
|
|
||||||
// align the cache at a page boundary
|
|
||||||
cache_code=(Bit8u*)(((long)cache_code_start_ptr + PAGESIZE_TEMP-1) & ~(PAGESIZE_TEMP-1)); //MEM LEAK. store old pointer if you want to free it.
|
|
||||||
|
|
||||||
cache_code_link_blocks=cache_code;
|
|
||||||
cache_code=cache_code+PAGESIZE_TEMP;
|
|
||||||
|
|
||||||
#if (C_HAVE_MPROTECT)
|
|
||||||
if(mprotect(cache_code_link_blocks,CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP,PROT_WRITE|PROT_READ|PROT_EXEC))
|
|
||||||
LOG_MSG("Setting excute permission on the code cache has failed");
|
|
||||||
#endif
|
|
||||||
CacheBlockDynRec * block=cache_getblock();
|
|
||||||
cache.block.first=block;
|
|
||||||
cache.block.active=block;
|
|
||||||
block->cache.start=&cache_code[0];
|
|
||||||
block->cache.size=CACHE_TOTAL;
|
|
||||||
block->cache.next=0; // last block in the list
|
|
||||||
}
|
|
||||||
// setup the default blocks for block linkage returns
|
|
||||||
cache.pos=&cache_code_link_blocks[0];
|
|
||||||
link_blocks[0].cache.start=cache.pos;
|
|
||||||
// link code that returns with a special return code
|
|
||||||
dyn_return(BR_Link1,false);
|
|
||||||
cache.pos=&cache_code_link_blocks[32];
|
|
||||||
link_blocks[1].cache.start=cache.pos;
|
|
||||||
// link code that returns with a special return code
|
|
||||||
dyn_return(BR_Link2,false);
|
|
||||||
|
|
||||||
cache.pos=&cache_code_link_blocks[64];
|
|
||||||
core_dynrec.runcode=(BlockReturn (*)(Bit8u*))cache.pos;
|
|
||||||
// link_blocks[1].cache.start=cache.pos;
|
|
||||||
dyn_run_code();
|
|
||||||
|
|
||||||
cache.free_pages=0;
|
|
||||||
cache.last_page=0;
|
|
||||||
cache.used_pages=0;
|
|
||||||
// setup the code pages
|
|
||||||
for (i=0;i<CACHE_PAGES;i++) {
|
|
||||||
CodePageHandlerDynRec * newpage=new CodePageHandlerDynRec();
|
|
||||||
newpage->next=cache.free_pages;
|
|
||||||
cache.free_pages=newpage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cache_close(void) {
|
|
||||||
/* for (;;) {
|
|
||||||
if (cache.used_pages) {
|
|
||||||
CodePageHandler * cpage=cache.used_pages;
|
|
||||||
CodePageHandler * npage=cache.used_pages->next;
|
|
||||||
cpage->ClearRelease();
|
|
||||||
delete cpage;
|
|
||||||
cache.used_pages=npage;
|
|
||||||
} else break;
|
|
||||||
}
|
|
||||||
if (cache_blocks != NULL) {
|
|
||||||
free(cache_blocks);
|
|
||||||
cache_blocks = NULL;
|
|
||||||
}
|
|
||||||
if (cache_code_start_ptr != NULL) {
|
|
||||||
### care: under windows VirtualFree() has to be used if
|
|
||||||
### VirtualAlloc was used for memory allocation
|
|
||||||
free(cache_code_start_ptr);
|
|
||||||
cache_code_start_ptr = NULL;
|
|
||||||
}
|
|
||||||
cache_code = NULL;
|
|
||||||
cache_code_link_blocks = NULL;
|
|
||||||
cache_initialized = false; */
|
|
||||||
}
|
|
@ -1,599 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2002-2008 The DOSBox Team
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* $Id: decoder.h,v 1.5 2008/09/19 16:48:02 c2woody Exp $ */
|
|
||||||
|
|
||||||
|
|
||||||
#include "decoder_basic.h"
|
|
||||||
#include "operators.h"
|
|
||||||
#include "decoder_opcodes.h"
|
|
||||||
|
|
||||||
#include "dyn_fpu.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
The function CreateCacheBlock translates the instruction stream
|
|
||||||
until either an unhandled instruction is found, the maximal
|
|
||||||
number of translated instructions is reached or some critical
|
|
||||||
instruction is encountered.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static CacheBlockDynRec * CreateCacheBlock(CodePageHandlerDynRec * codepage,PhysPt start,Bitu max_opcodes) {
|
|
||||||
// initialize a load of variables
|
|
||||||
decode.code_start=start;
|
|
||||||
decode.code=start;
|
|
||||||
decode.page.code=codepage;
|
|
||||||
decode.page.index=start&4095;
|
|
||||||
decode.page.wmap=codepage->write_map;
|
|
||||||
decode.page.invmap=codepage->invalidation_map;
|
|
||||||
decode.page.first=start >> 12;
|
|
||||||
decode.active_block=decode.block=cache_openblock();
|
|
||||||
decode.block->page.start=(Bit16u)decode.page.index;
|
|
||||||
codepage->AddCacheBlock(decode.block);
|
|
||||||
|
|
||||||
InitFlagsOptimization();
|
|
||||||
|
|
||||||
// every codeblock that is run sets cache.block.running to itself
|
|
||||||
// so the block linking knows the last executed block
|
|
||||||
gen_mov_direct_ptr(&cache.block.running,(DRC_PTR_SIZE_IM)decode.block);
|
|
||||||
|
|
||||||
// start with the cycles check
|
|
||||||
gen_mov_word_to_reg(FC_RETOP,&CPU_Cycles,true);
|
|
||||||
save_info_dynrec[used_save_info_dynrec].branch_pos=gen_create_branch_long_leqzero(FC_RETOP);
|
|
||||||
save_info_dynrec[used_save_info_dynrec].type=cycle_check;
|
|
||||||
used_save_info_dynrec++;
|
|
||||||
|
|
||||||
decode.cycles=0;
|
|
||||||
while (max_opcodes--) {
|
|
||||||
// Init prefixes
|
|
||||||
decode.big_addr=cpu.code.big;
|
|
||||||
decode.big_op=cpu.code.big;
|
|
||||||
decode.seg_prefix=0;
|
|
||||||
decode.seg_prefix_used=false;
|
|
||||||
decode.rep=REP_NONE;
|
|
||||||
decode.cycles++;
|
|
||||||
decode.op_start=decode.code;
|
|
||||||
restart_prefix:
|
|
||||||
Bitu opcode;
|
|
||||||
if (!decode.page.invmap) opcode=decode_fetchb();
|
|
||||||
else {
|
|
||||||
// some entries in the invalidation map, see if the next
|
|
||||||
// instruction is known to be modified a lot
|
|
||||||
if (decode.page.index<4096) {
|
|
||||||
if (GCC_UNLIKELY(decode.page.invmap[decode.page.index]>=4)) goto illegalopcode;
|
|
||||||
opcode=decode_fetchb();
|
|
||||||
} else {
|
|
||||||
// switch to the next page
|
|
||||||
opcode=decode_fetchb();
|
|
||||||
if (GCC_UNLIKELY(decode.page.invmap &&
|
|
||||||
(decode.page.invmap[decode.page.index-1]>=4))) goto illegalopcode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
switch (opcode) {
|
|
||||||
// instructions 'op reg8,reg8' and 'op [],reg8'
|
|
||||||
case 0x00:dyn_dop_ebgb(DOP_ADD);break;
|
|
||||||
case 0x08:dyn_dop_ebgb(DOP_OR);break;
|
|
||||||
case 0x10:dyn_dop_ebgb(DOP_ADC);break;
|
|
||||||
case 0x18:dyn_dop_ebgb(DOP_SBB);break;
|
|
||||||
case 0x20:dyn_dop_ebgb(DOP_AND);break;
|
|
||||||
case 0x28:dyn_dop_ebgb(DOP_SUB);break;
|
|
||||||
case 0x30:dyn_dop_ebgb(DOP_XOR);break;
|
|
||||||
case 0x38:dyn_dop_ebgb(DOP_CMP);break;
|
|
||||||
|
|
||||||
// instructions 'op reg8,reg8' and 'op reg8,[]'
|
|
||||||
case 0x02:dyn_dop_gbeb(DOP_ADD);break;
|
|
||||||
case 0x0a:dyn_dop_gbeb(DOP_OR);break;
|
|
||||||
case 0x12:dyn_dop_gbeb(DOP_ADC);break;
|
|
||||||
case 0x1a:dyn_dop_gbeb(DOP_SBB);break;
|
|
||||||
case 0x22:dyn_dop_gbeb(DOP_AND);break;
|
|
||||||
case 0x2a:dyn_dop_gbeb(DOP_SUB);break;
|
|
||||||
case 0x32:dyn_dop_gbeb(DOP_XOR);break;
|
|
||||||
case 0x3a:dyn_dop_gbeb(DOP_CMP);break;
|
|
||||||
|
|
||||||
// instructions 'op reg16/32,reg16/32' and 'op [],reg16/32'
|
|
||||||
case 0x01:dyn_dop_evgv(DOP_ADD);break;
|
|
||||||
case 0x09:dyn_dop_evgv(DOP_OR);break;
|
|
||||||
case 0x11:dyn_dop_evgv(DOP_ADC);break;
|
|
||||||
case 0x19:dyn_dop_evgv(DOP_SBB);break;
|
|
||||||
case 0x21:dyn_dop_evgv(DOP_AND);break;
|
|
||||||
case 0x29:dyn_dop_evgv(DOP_SUB);break;
|
|
||||||
case 0x31:dyn_dop_evgv(DOP_XOR);break;
|
|
||||||
case 0x39:dyn_dop_evgv(DOP_CMP);break;
|
|
||||||
|
|
||||||
// instructions 'op reg16/32,reg16/32' and 'op reg16/32,[]'
|
|
||||||
case 0x03:dyn_dop_gvev(DOP_ADD);break;
|
|
||||||
case 0x0b:dyn_dop_gvev(DOP_OR);break;
|
|
||||||
case 0x13:dyn_dop_gvev(DOP_ADC);break;
|
|
||||||
case 0x1b:dyn_dop_gvev(DOP_SBB);break;
|
|
||||||
case 0x23:dyn_dop_gvev(DOP_AND);break;
|
|
||||||
case 0x2b:dyn_dop_gvev(DOP_SUB);break;
|
|
||||||
case 0x33:dyn_dop_gvev(DOP_XOR);break;
|
|
||||||
case 0x3b:dyn_dop_gvev(DOP_CMP);break;
|
|
||||||
|
|
||||||
// instructions 'op reg8,imm8'
|
|
||||||
case 0x04:dyn_dop_byte_imm(DOP_ADD,DRC_REG_EAX,0);break;
|
|
||||||
case 0x0c:dyn_dop_byte_imm(DOP_OR,DRC_REG_EAX,0);break;
|
|
||||||
case 0x14:dyn_dop_byte_imm(DOP_ADC,DRC_REG_EAX,0);break;
|
|
||||||
case 0x1c:dyn_dop_byte_imm(DOP_SBB,DRC_REG_EAX,0);break;
|
|
||||||
case 0x24:dyn_dop_byte_imm(DOP_AND,DRC_REG_EAX,0);break;
|
|
||||||
case 0x2c:dyn_dop_byte_imm(DOP_SUB,DRC_REG_EAX,0);break;
|
|
||||||
case 0x34:dyn_dop_byte_imm(DOP_XOR,DRC_REG_EAX,0);break;
|
|
||||||
case 0x3c:dyn_dop_byte_imm(DOP_CMP,DRC_REG_EAX,0);break;
|
|
||||||
|
|
||||||
// instructions 'op reg16/32,imm16/32'
|
|
||||||
case 0x05:dyn_dop_word_imm(DOP_ADD,DRC_REG_EAX);break;
|
|
||||||
case 0x0d:dyn_dop_word_imm_old(DOP_OR,DRC_REG_EAX,decode.big_op ? decode_fetchd() : decode_fetchw());break;
|
|
||||||
case 0x15:dyn_dop_word_imm_old(DOP_ADC,DRC_REG_EAX,decode.big_op ? decode_fetchd() : decode_fetchw());break;
|
|
||||||
case 0x1d:dyn_dop_word_imm_old(DOP_SBB,DRC_REG_EAX,decode.big_op ? decode_fetchd() : decode_fetchw());break;
|
|
||||||
case 0x25:dyn_dop_word_imm(DOP_AND,DRC_REG_EAX);break;
|
|
||||||
case 0x2d:dyn_dop_word_imm_old(DOP_SUB,DRC_REG_EAX,decode.big_op ? decode_fetchd() : decode_fetchw());break;
|
|
||||||
case 0x35:dyn_dop_word_imm_old(DOP_XOR,DRC_REG_EAX,decode.big_op ? decode_fetchd() : decode_fetchw());break;
|
|
||||||
case 0x3d:dyn_dop_word_imm_old(DOP_CMP,DRC_REG_EAX,decode.big_op ? decode_fetchd() : decode_fetchw());break;
|
|
||||||
|
|
||||||
// push segment register onto stack
|
|
||||||
case 0x06:dyn_push_seg(DRC_SEG_ES);break;
|
|
||||||
case 0x0e:dyn_push_seg(DRC_SEG_CS);break;
|
|
||||||
case 0x16:dyn_push_seg(DRC_SEG_SS);break;
|
|
||||||
case 0x1e:dyn_push_seg(DRC_SEG_DS);break;
|
|
||||||
|
|
||||||
// pop segment register from stack
|
|
||||||
case 0x07:dyn_pop_seg(DRC_SEG_ES);break;
|
|
||||||
case 0x17:dyn_pop_seg(DRC_SEG_SS);break;
|
|
||||||
case 0x1f:dyn_pop_seg(DRC_SEG_DS);break;
|
|
||||||
|
|
||||||
// segment prefixes
|
|
||||||
case 0x26:dyn_segprefix(DRC_SEG_ES);goto restart_prefix;
|
|
||||||
case 0x2e:dyn_segprefix(DRC_SEG_CS);goto restart_prefix;
|
|
||||||
case 0x36:dyn_segprefix(DRC_SEG_SS);goto restart_prefix;
|
|
||||||
case 0x3e:dyn_segprefix(DRC_SEG_DS);goto restart_prefix;
|
|
||||||
case 0x64:dyn_segprefix(DRC_SEG_FS);goto restart_prefix;
|
|
||||||
case 0x65:dyn_segprefix(DRC_SEG_GS);goto restart_prefix;
|
|
||||||
|
|
||||||
// case 0x27: DAA missing
|
|
||||||
// case 0x2f: DAS missing
|
|
||||||
// case 0x37: AAA missing
|
|
||||||
// case 0x3f: AAS missing
|
|
||||||
|
|
||||||
// dual opcodes
|
|
||||||
case 0x0f:
|
|
||||||
{
|
|
||||||
Bitu dual_code=decode_fetchb();
|
|
||||||
switch (dual_code) {
|
|
||||||
case 0x00:
|
|
||||||
if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegalopcode;
|
|
||||||
dyn_grp6();
|
|
||||||
break;
|
|
||||||
case 0x01:
|
|
||||||
if (dyn_grp7()) goto finish_block;
|
|
||||||
break;
|
|
||||||
/* case 0x02:
|
|
||||||
if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegalopcode;
|
|
||||||
dyn_larlsl(true);
|
|
||||||
break;
|
|
||||||
case 0x03:
|
|
||||||
if ((reg_flags & FLAG_VM) || (!cpu.pmode)) goto illegalopcode;
|
|
||||||
dyn_larlsl(false);
|
|
||||||
break; */
|
|
||||||
|
|
||||||
case 0x20:dyn_mov_from_crx();break;
|
|
||||||
case 0x22:dyn_mov_to_crx();goto finish_block;
|
|
||||||
|
|
||||||
// short conditional jumps
|
|
||||||
case 0x80:case 0x81:case 0x82:case 0x83:case 0x84:case 0x85:case 0x86:case 0x87:
|
|
||||||
case 0x88:case 0x89:case 0x8a:case 0x8b:case 0x8c:case 0x8d:case 0x8e:case 0x8f:
|
|
||||||
dyn_branched_exit((BranchTypes)(dual_code&0xf),
|
|
||||||
decode.big_op ? (Bit32s)decode_fetchd() : (Bit16s)decode_fetchw());
|
|
||||||
goto finish_block;
|
|
||||||
|
|
||||||
// conditional byte set instructions
|
|
||||||
/* case 0x90:case 0x91:case 0x92:case 0x93:case 0x94:case 0x95:case 0x96:case 0x97:
|
|
||||||
case 0x98:case 0x99:case 0x9a:case 0x9b:case 0x9c:case 0x9d:case 0x9e:case 0x9f:
|
|
||||||
dyn_set_byte_on_condition((BranchTypes)(dual_code&0xf));
|
|
||||||
AcquireFlags(FMASK_TEST);
|
|
||||||
break; */
|
|
||||||
|
|
||||||
// push/pop segment registers
|
|
||||||
case 0xa0:dyn_push_seg(DRC_SEG_FS);break;
|
|
||||||
case 0xa1:dyn_pop_seg(DRC_SEG_FS);break;
|
|
||||||
case 0xa8:dyn_push_seg(DRC_SEG_GS);break;
|
|
||||||
case 0xa9:dyn_pop_seg(DRC_SEG_GS);break;
|
|
||||||
|
|
||||||
// double shift instructions
|
|
||||||
case 0xa4:dyn_dshift_ev_gv(true,true);break;
|
|
||||||
case 0xa5:dyn_dshift_ev_gv(true,false);break;
|
|
||||||
case 0xac:dyn_dshift_ev_gv(false,true);break;
|
|
||||||
case 0xad:dyn_dshift_ev_gv(false,false);break;
|
|
||||||
|
|
||||||
case 0xaf:dyn_imul_gvev(0);break;
|
|
||||||
|
|
||||||
// lfs
|
|
||||||
case 0xb4:
|
|
||||||
dyn_get_modrm();
|
|
||||||
if (GCC_UNLIKELY(decode.modrm.mod==3)) goto illegalopcode;
|
|
||||||
dyn_load_seg_off_ea(DRC_SEG_FS);
|
|
||||||
break;
|
|
||||||
// lgs
|
|
||||||
case 0xb5:
|
|
||||||
dyn_get_modrm();
|
|
||||||
if (GCC_UNLIKELY(decode.modrm.mod==3)) goto illegalopcode;
|
|
||||||
dyn_load_seg_off_ea(DRC_SEG_GS);
|
|
||||||
break;
|
|
||||||
|
|
||||||
// zero-extending moves
|
|
||||||
case 0xb6:dyn_movx_ev_gb(false);break;
|
|
||||||
case 0xb7:dyn_movx_ev_gw(false);break;
|
|
||||||
|
|
||||||
// sign-extending moves
|
|
||||||
case 0xbe:dyn_movx_ev_gb(true);break;
|
|
||||||
case 0xbf:dyn_movx_ev_gw(true);break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
// DYN_LOG("Unhandled dual opcode 0F%02X",dual_code);
|
|
||||||
goto illegalopcode;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 'inc/dec reg16/32'
|
|
||||||
case 0x40:case 0x41:case 0x42:case 0x43:case 0x44:case 0x45:case 0x46:case 0x47:
|
|
||||||
dyn_sop_word(SOP_INC,opcode&7);
|
|
||||||
break;
|
|
||||||
case 0x48:case 0x49:case 0x4a:case 0x4b:case 0x4c:case 0x4d:case 0x4e:case 0x4f:
|
|
||||||
dyn_sop_word(SOP_DEC,opcode&7);
|
|
||||||
break;
|
|
||||||
|
|
||||||
// 'push/pop reg16/32'
|
|
||||||
case 0x50:case 0x51:case 0x52:case 0x53:case 0x54:case 0x55:case 0x56:case 0x57:
|
|
||||||
dyn_push_reg(opcode&7);
|
|
||||||
break;
|
|
||||||
case 0x58:case 0x59:case 0x5a:case 0x5b:case 0x5c:case 0x5d:case 0x5e:case 0x5f:
|
|
||||||
dyn_pop_reg(opcode&7);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x60:
|
|
||||||
if (decode.big_op) gen_call_function_raw((void *)&dynrec_pusha_dword);
|
|
||||||
else gen_call_function_raw((void *)&dynrec_pusha_word);
|
|
||||||
break;
|
|
||||||
case 0x61:
|
|
||||||
if (decode.big_op) gen_call_function_raw((void *)&dynrec_popa_dword);
|
|
||||||
else gen_call_function_raw((void *)&dynrec_popa_word);
|
|
||||||
break;
|
|
||||||
|
|
||||||
// case 0x62: BOUND missing
|
|
||||||
// case 0x61: ARPL missing
|
|
||||||
|
|
||||||
case 0x66:decode.big_op=!cpu.code.big;goto restart_prefix;
|
|
||||||
case 0x67:decode.big_addr=!cpu.code.big;goto restart_prefix;
|
|
||||||
|
|
||||||
// 'push imm8/16/32'
|
|
||||||
case 0x68:
|
|
||||||
dyn_push_word_imm(decode.big_op ? decode_fetchd() : decode_fetchw());
|
|
||||||
break;
|
|
||||||
case 0x6a:
|
|
||||||
dyn_push_byte_imm((Bit8s)decode_fetchb());
|
|
||||||
break;
|
|
||||||
|
|
||||||
// signed multiplication
|
|
||||||
case 0x69:dyn_imul_gvev(decode.big_op ? 4 : 2);break;
|
|
||||||
case 0x6b:dyn_imul_gvev(1);break;
|
|
||||||
|
|
||||||
// case 0x6c to 0x6f missing (ins/outs)
|
|
||||||
|
|
||||||
// short conditional jumps
|
|
||||||
case 0x70:case 0x71:case 0x72:case 0x73:case 0x74:case 0x75:case 0x76:case 0x77:
|
|
||||||
case 0x78:case 0x79:case 0x7a:case 0x7b:case 0x7c:case 0x7d:case 0x7e:case 0x7f:
|
|
||||||
dyn_branched_exit((BranchTypes)(opcode&0xf),(Bit8s)decode_fetchb());
|
|
||||||
goto finish_block;
|
|
||||||
|
|
||||||
// 'op []/reg8,imm8'
|
|
||||||
case 0x80:
|
|
||||||
case 0x82:dyn_grp1_eb_ib();break;
|
|
||||||
|
|
||||||
// 'op []/reg16/32,imm16/32'
|
|
||||||
case 0x81:dyn_grp1_ev_iv(false);break;
|
|
||||||
case 0x83:dyn_grp1_ev_iv(true);break;
|
|
||||||
|
|
||||||
// 'test []/reg8/16/32,reg8/16/32'
|
|
||||||
case 0x84:dyn_dop_gbeb(DOP_TEST);break;
|
|
||||||
case 0x85:dyn_dop_gvev(DOP_TEST);break;
|
|
||||||
|
|
||||||
// 'xchg reg8/16/32,[]/reg8/16/32'
|
|
||||||
case 0x86:dyn_dop_ebgb_xchg();break;
|
|
||||||
case 0x87:dyn_dop_evgv_xchg();break;
|
|
||||||
|
|
||||||
// 'mov []/reg8/16/32,reg8/16/32'
|
|
||||||
case 0x88:dyn_dop_ebgb_mov();break;
|
|
||||||
case 0x89:dyn_dop_evgv_mov();break;
|
|
||||||
// 'mov reg8/16/32,[]/reg8/16/32'
|
|
||||||
case 0x8a:dyn_dop_gbeb_mov();break;
|
|
||||||
case 0x8b:dyn_dop_gvev_mov();break;
|
|
||||||
|
|
||||||
// move segment register into memory or a 16bit register
|
|
||||||
case 0x8c:dyn_mov_ev_seg();break;
|
|
||||||
|
|
||||||
// load effective address
|
|
||||||
case 0x8d:dyn_lea();break;
|
|
||||||
|
|
||||||
// move a value from memory or a 16bit register into a segment register
|
|
||||||
case 0x8e:dyn_mov_seg_ev();break;
|
|
||||||
|
|
||||||
// 'pop []'
|
|
||||||
case 0x8f:dyn_pop_ev();break;
|
|
||||||
|
|
||||||
case 0x90: // nop
|
|
||||||
case 0x9b: // wait
|
|
||||||
case 0xf0: // lock
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x91:case 0x92:case 0x93:case 0x94:case 0x95:case 0x96:case 0x97:
|
|
||||||
dyn_xchg_ax(opcode&7);
|
|
||||||
break;
|
|
||||||
|
|
||||||
// sign-extend al into ax/sign-extend ax into eax
|
|
||||||
case 0x98:dyn_cbw();break;
|
|
||||||
// sign-extend ax into dx:ax/sign-extend eax into edx:eax
|
|
||||||
case 0x99:dyn_cwd();break;
|
|
||||||
|
|
||||||
case 0x9a:dyn_call_far_imm();goto finish_block;
|
|
||||||
|
|
||||||
case 0x9c: // pushf
|
|
||||||
AcquireFlags(FMASK_TEST);
|
|
||||||
gen_call_function_I((void *)&CPU_PUSHF,decode.big_op);
|
|
||||||
dyn_check_exception(FC_RETOP);
|
|
||||||
break;
|
|
||||||
case 0x9d: // popf
|
|
||||||
gen_call_function_I((void *)&CPU_POPF,decode.big_op);
|
|
||||||
dyn_check_exception(FC_RETOP);
|
|
||||||
InvalidateFlags();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x9e:dyn_sahf();break;
|
|
||||||
// case 0x9f: LAHF missing
|
|
||||||
|
|
||||||
// 'mov al/ax,[]'
|
|
||||||
case 0xa0:
|
|
||||||
dyn_mov_byte_al_direct(decode.big_addr ? decode_fetchd() : decode_fetchw());
|
|
||||||
break;
|
|
||||||
case 0xa1:
|
|
||||||
dyn_mov_byte_ax_direct(decode.big_addr ? decode_fetchd() : decode_fetchw());
|
|
||||||
break;
|
|
||||||
// 'mov [],al/ax'
|
|
||||||
case 0xa2:
|
|
||||||
dyn_mov_byte_direct_al();
|
|
||||||
break;
|
|
||||||
case 0xa3:
|
|
||||||
dyn_mov_byte_direct_ax(decode.big_addr ? decode_fetchd() : decode_fetchw());
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
// case 0xa6 to 0xaf string operations, some missing
|
|
||||||
|
|
||||||
// movsb/w/d
|
|
||||||
case 0xa4:dyn_string(STR_MOVSB);break;
|
|
||||||
case 0xa5:dyn_string(decode.big_op ? STR_MOVSD : STR_MOVSW);break;
|
|
||||||
|
|
||||||
// stosb/w/d
|
|
||||||
case 0xaa:dyn_string(STR_STOSB);break;
|
|
||||||
case 0xab:dyn_string(decode.big_op ? STR_STOSD : STR_STOSW);break;
|
|
||||||
|
|
||||||
// lodsb/w/d
|
|
||||||
case 0xac:dyn_string(STR_LODSB);break;
|
|
||||||
case 0xad:dyn_string(decode.big_op ? STR_LODSD : STR_LODSW);break;
|
|
||||||
|
|
||||||
|
|
||||||
// 'test reg8/16/32,imm8/16/32'
|
|
||||||
case 0xa8:dyn_dop_byte_imm(DOP_TEST,DRC_REG_EAX,0);break;
|
|
||||||
case 0xa9:dyn_dop_word_imm_old(DOP_TEST,DRC_REG_EAX,decode.big_op ? decode_fetchd() : decode_fetchw());break;
|
|
||||||
|
|
||||||
// 'mov reg8/16/32,imm8/16/32'
|
|
||||||
case 0xb0:case 0xb1:case 0xb2:case 0xb3:case 0xb4:case 0xb5:case 0xb6:case 0xb7:
|
|
||||||
dyn_mov_byte_imm(opcode&3,(opcode>>2)&1,decode_fetchb());
|
|
||||||
break;
|
|
||||||
case 0xb8:case 0xb9:case 0xba:case 0xbb:case 0xbc:case 0xbd:case 0xbe:case 0xbf:
|
|
||||||
dyn_mov_word_imm(opcode&7);break;
|
|
||||||
break;
|
|
||||||
|
|
||||||
// 'shiftop []/reg8,imm8/1/cl'
|
|
||||||
case 0xc0:dyn_grp2_eb(grp2_imm);break;
|
|
||||||
case 0xd0:dyn_grp2_eb(grp2_1);break;
|
|
||||||
case 0xd2:dyn_grp2_eb(grp2_cl);break;
|
|
||||||
|
|
||||||
// 'shiftop []/reg16/32,imm8/1/cl'
|
|
||||||
case 0xc1:dyn_grp2_ev(grp2_imm);break;
|
|
||||||
case 0xd1:dyn_grp2_ev(grp2_1);break;
|
|
||||||
case 0xd3:dyn_grp2_ev(grp2_cl);break;
|
|
||||||
|
|
||||||
// retn [param]
|
|
||||||
case 0xc2:dyn_ret_near(decode_fetchw());goto finish_block;
|
|
||||||
case 0xc3:dyn_ret_near(0);goto finish_block;
|
|
||||||
|
|
||||||
// les
|
|
||||||
case 0xc4:
|
|
||||||
dyn_get_modrm();
|
|
||||||
if (GCC_UNLIKELY(decode.modrm.mod==3)) goto illegalopcode;
|
|
||||||
dyn_load_seg_off_ea(DRC_SEG_ES);
|
|
||||||
break;
|
|
||||||
// lds
|
|
||||||
case 0xc5:
|
|
||||||
dyn_get_modrm();
|
|
||||||
if (GCC_UNLIKELY(decode.modrm.mod==3)) goto illegalopcode;
|
|
||||||
dyn_load_seg_off_ea(DRC_SEG_DS);break;
|
|
||||||
|
|
||||||
// 'mov []/reg8/16/32,imm8/16/32'
|
|
||||||
case 0xc6:dyn_dop_ebib_mov();break;
|
|
||||||
case 0xc7:dyn_dop_eviv_mov();break;
|
|
||||||
|
|
||||||
case 0xc8:dyn_enter();break;
|
|
||||||
case 0xc9:dyn_leave();break;
|
|
||||||
|
|
||||||
// retf [param]
|
|
||||||
case 0xca:dyn_ret_far(decode_fetchw());goto finish_block;
|
|
||||||
case 0xcb:dyn_ret_far(0);goto finish_block;
|
|
||||||
|
|
||||||
// int/iret
|
|
||||||
case 0xcd:dyn_interrupt(decode_fetchb());goto finish_block;
|
|
||||||
case 0xcf:dyn_iret();goto finish_block;
|
|
||||||
|
|
||||||
// case 0xd4: AAM missing
|
|
||||||
// case 0xd5: AAD missing
|
|
||||||
|
|
||||||
// case 0xd6: SALC missing
|
|
||||||
// case 0xd7: XLAT missing
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef CPU_FPU
|
|
||||||
// floating point instructions
|
|
||||||
case 0xd8:
|
|
||||||
dyn_fpu_esc0();
|
|
||||||
break;
|
|
||||||
case 0xd9:
|
|
||||||
dyn_fpu_esc1();
|
|
||||||
break;
|
|
||||||
case 0xda:
|
|
||||||
dyn_fpu_esc2();
|
|
||||||
break;
|
|
||||||
case 0xdb:
|
|
||||||
dyn_fpu_esc3();
|
|
||||||
break;
|
|
||||||
case 0xdc:
|
|
||||||
dyn_fpu_esc4();
|
|
||||||
break;
|
|
||||||
case 0xdd:
|
|
||||||
dyn_fpu_esc5();
|
|
||||||
break;
|
|
||||||
case 0xde:
|
|
||||||
dyn_fpu_esc6();
|
|
||||||
break;
|
|
||||||
case 0xdf:
|
|
||||||
dyn_fpu_esc7();
|
|
||||||
break;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// loop instructions
|
|
||||||
case 0xe0:dyn_loop(LOOP_NE);goto finish_block;
|
|
||||||
case 0xe1:dyn_loop(LOOP_E);goto finish_block;
|
|
||||||
case 0xe2:dyn_loop(LOOP_NONE);goto finish_block;
|
|
||||||
case 0xe3:dyn_loop(LOOP_JCXZ);goto finish_block;
|
|
||||||
|
|
||||||
|
|
||||||
// 'in al/ax/eax,port_imm'
|
|
||||||
case 0xe4:dyn_read_port_byte_direct(decode_fetchb());break;
|
|
||||||
case 0xe5:dyn_read_port_word_direct(decode_fetchb());break;
|
|
||||||
// 'out port_imm,al/ax/eax'
|
|
||||||
case 0xe6:dyn_write_port_byte_direct(decode_fetchb());break;
|
|
||||||
case 0xe7:dyn_write_port_word_direct(decode_fetchb());break;
|
|
||||||
|
|
||||||
// 'in al/ax/eax,port_dx'
|
|
||||||
case 0xec:dyn_read_port_byte();break;
|
|
||||||
case 0xed:dyn_read_port_word();break;
|
|
||||||
// 'out port_dx,al/ax/eax'
|
|
||||||
case 0xee:dyn_write_port_byte();break;
|
|
||||||
case 0xef:dyn_write_port_word();break;
|
|
||||||
|
|
||||||
|
|
||||||
// 'call near imm16/32'
|
|
||||||
case 0xe8:
|
|
||||||
dyn_call_near_imm();
|
|
||||||
goto finish_block;
|
|
||||||
// 'jmp near imm16/32'
|
|
||||||
case 0xe9:
|
|
||||||
dyn_exit_link(decode.big_op ? (Bit32s)decode_fetchd() : (Bit16s)decode_fetchw());
|
|
||||||
goto finish_block;
|
|
||||||
// 'jmp far'
|
|
||||||
case 0xea:
|
|
||||||
dyn_jmp_far_imm();
|
|
||||||
goto finish_block;
|
|
||||||
// 'jmp short imm8'
|
|
||||||
case 0xeb:
|
|
||||||
dyn_exit_link((Bit8s)decode_fetchb());
|
|
||||||
goto finish_block;
|
|
||||||
|
|
||||||
|
|
||||||
// repeat prefixes
|
|
||||||
case 0xf2:
|
|
||||||
decode.rep=REP_NZ;
|
|
||||||
goto restart_prefix;
|
|
||||||
case 0xf3:
|
|
||||||
decode.rep=REP_Z;
|
|
||||||
goto restart_prefix;
|
|
||||||
|
|
||||||
case 0xf5: //CMC
|
|
||||||
gen_call_function_raw((void*)dynrec_cmc);
|
|
||||||
break;
|
|
||||||
case 0xf8: //CLC
|
|
||||||
gen_call_function_raw((void*)dynrec_clc);
|
|
||||||
break;
|
|
||||||
case 0xf9: //STC
|
|
||||||
gen_call_function_raw((void*)dynrec_stc);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0xf6:dyn_grp3_eb();break;
|
|
||||||
case 0xf7:dyn_grp3_ev();break;
|
|
||||||
|
|
||||||
case 0xfa: //CLI
|
|
||||||
gen_call_function_raw((void *)&CPU_CLI);
|
|
||||||
dyn_check_exception(FC_RETOP);
|
|
||||||
break;
|
|
||||||
case 0xfb: //STI
|
|
||||||
gen_call_function_raw((void *)&CPU_STI);
|
|
||||||
dyn_check_exception(FC_RETOP);
|
|
||||||
if (max_opcodes<=0) max_opcodes=1; //Allow 1 extra opcode
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0xfc: //CLD
|
|
||||||
gen_call_function_raw((void*)dynrec_cld);
|
|
||||||
break;
|
|
||||||
case 0xfd: //STD
|
|
||||||
gen_call_function_raw((void*)dynrec_std);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0xfe:
|
|
||||||
if (dyn_grp4_eb()) goto finish_block;
|
|
||||||
break;
|
|
||||||
case 0xff:
|
|
||||||
if (dyn_grp4_ev()) goto core_close_block;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
// DYN_LOG("Dynrec unhandled opcode %X",opcode);
|
|
||||||
goto illegalopcode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// normal exit because the maximal number of opcodes has been reached
|
|
||||||
dyn_set_eip_end();
|
|
||||||
core_close_block:
|
|
||||||
dyn_reduce_cycles();
|
|
||||||
dyn_return(BR_Normal);
|
|
||||||
dyn_closeblock();
|
|
||||||
goto finish_block;
|
|
||||||
illegalopcode:
|
|
||||||
// some unhandled opcode has been encountered
|
|
||||||
dyn_set_eip_last();
|
|
||||||
dyn_reduce_cycles();
|
|
||||||
dyn_return(BR_Opcode); // tell the core what happened
|
|
||||||
dyn_closeblock();
|
|
||||||
goto finish_block;
|
|
||||||
finish_block:
|
|
||||||
|
|
||||||
// setup the correct end-address
|
|
||||||
decode.page.index--;
|
|
||||||
decode.active_block->page.end=(Bit16u)decode.page.index;
|
|
||||||
// LOG_MSG("Created block size %d start %d end %d",decode.block->cache.size,decode.block->page.start,decode.block->page.end);
|
|
||||||
|
|
||||||
return decode.block;
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,681 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2002-2008 The DOSBox Team
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "dosbox.h"
|
|
||||||
#if C_FPU
|
|
||||||
|
|
||||||
#include <math.h>
|
|
||||||
#include <float.h>
|
|
||||||
#include "cross.h"
|
|
||||||
#include "mem.h"
|
|
||||||
#include "fpu.h"
|
|
||||||
#include "cpu.h"
|
|
||||||
|
|
||||||
|
|
||||||
static void FPU_FDECSTP(){
|
|
||||||
TOP = (TOP - 1) & 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void FPU_FINCSTP(){
|
|
||||||
TOP = (TOP + 1) & 7;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void FPU_FNSTCW(PhysPt addr){
|
|
||||||
mem_writew(addr,fpu.cw);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void FPU_FFREE(Bitu st) {
|
|
||||||
fpu.tags[st]=TAG_Empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if C_FPU_X86
|
|
||||||
#include "../../fpu/fpu_instructions_x86.h"
|
|
||||||
#else
|
|
||||||
#include "../../fpu/fpu_instructions.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
static INLINE void dyn_fpu_top() {
|
|
||||||
gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true);
|
|
||||||
gen_add_imm(FC_OP2,decode.modrm.rm);
|
|
||||||
gen_and_imm(FC_OP2,7);
|
|
||||||
gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static INLINE void dyn_fpu_top_swapped() {
|
|
||||||
gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true);
|
|
||||||
gen_add_imm(FC_OP1,decode.modrm.rm);
|
|
||||||
gen_and_imm(FC_OP1,7);
|
|
||||||
gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dyn_eatree() {
|
|
||||||
Bitu group=(decode.modrm.val >> 3) & 7;
|
|
||||||
switch (group){
|
|
||||||
case 0x00: // FADD ST,STi
|
|
||||||
gen_call_function_R((void*)&FPU_FADD_EA,FC_OP1);
|
|
||||||
break;
|
|
||||||
case 0x01: // FMUL ST,STi
|
|
||||||
gen_call_function_R((void*)&FPU_FMUL_EA,FC_OP1);
|
|
||||||
break;
|
|
||||||
case 0x02: // FCOM STi
|
|
||||||
gen_call_function_R((void*)&FPU_FCOM_EA,FC_OP1);
|
|
||||||
break;
|
|
||||||
case 0x03: // FCOMP STi
|
|
||||||
gen_call_function_R((void*)&FPU_FCOM_EA,FC_OP1);
|
|
||||||
gen_call_function_raw((void*)&FPU_FPOP);
|
|
||||||
break;
|
|
||||||
case 0x04: // FSUB ST,STi
|
|
||||||
gen_call_function_R((void*)&FPU_FSUB_EA,FC_OP1);
|
|
||||||
break;
|
|
||||||
case 0x05: // FSUBR ST,STi
|
|
||||||
gen_call_function_R((void*)&FPU_FSUBR_EA,FC_OP1);
|
|
||||||
break;
|
|
||||||
case 0x06: // FDIV ST,STi
|
|
||||||
gen_call_function_R((void*)&FPU_FDIV_EA,FC_OP1);
|
|
||||||
break;
|
|
||||||
case 0x07: // FDIVR ST,STi
|
|
||||||
gen_call_function_R((void*)&FPU_FDIVR_EA,FC_OP1);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dyn_fpu_esc0(){
|
|
||||||
dyn_get_modrm();
|
|
||||||
if (decode.modrm.val >= 0xc0) {
|
|
||||||
dyn_fpu_top();
|
|
||||||
switch (decode.modrm.reg){
|
|
||||||
case 0x00: //FADD ST,STi
|
|
||||||
gen_call_function_RR((void*)&FPU_FADD,FC_OP1,FC_OP2);
|
|
||||||
break;
|
|
||||||
case 0x01: // FMUL ST,STi
|
|
||||||
gen_call_function_RR((void*)&FPU_FMUL,FC_OP1,FC_OP2);
|
|
||||||
break;
|
|
||||||
case 0x02: // FCOM STi
|
|
||||||
gen_call_function_RR((void*)&FPU_FCOM,FC_OP1,FC_OP2);
|
|
||||||
break;
|
|
||||||
case 0x03: // FCOMP STi
|
|
||||||
gen_call_function_RR((void*)&FPU_FCOM,FC_OP1,FC_OP2);
|
|
||||||
gen_call_function_raw((void*)&FPU_FPOP);
|
|
||||||
break;
|
|
||||||
case 0x04: // FSUB ST,STi
|
|
||||||
gen_call_function_RR((void*)&FPU_FSUB,FC_OP1,FC_OP2);
|
|
||||||
break;
|
|
||||||
case 0x05: // FSUBR ST,STi
|
|
||||||
gen_call_function_RR((void*)&FPU_FSUBR,FC_OP1,FC_OP2);
|
|
||||||
break;
|
|
||||||
case 0x06: // FDIV ST,STi
|
|
||||||
gen_call_function_RR((void*)&FPU_FDIV,FC_OP1,FC_OP2);
|
|
||||||
break;
|
|
||||||
case 0x07: // FDIVR ST,STi
|
|
||||||
gen_call_function_RR((void*)&FPU_FDIVR,FC_OP1,FC_OP2);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dyn_fill_ea(FC_ADDR);
|
|
||||||
gen_call_function_R((void*)&FPU_FLD_F32_EA,FC_ADDR);
|
|
||||||
gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true);
|
|
||||||
dyn_eatree();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void dyn_fpu_esc1(){
|
|
||||||
dyn_get_modrm();
|
|
||||||
if (decode.modrm.val >= 0xc0) {
|
|
||||||
switch (decode.modrm.reg){
|
|
||||||
case 0x00: /* FLD STi */
|
|
||||||
gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true);
|
|
||||||
gen_add_imm(FC_OP1,decode.modrm.rm);
|
|
||||||
gen_and_imm(FC_OP1,7);
|
|
||||||
gen_protect_reg(FC_OP1);
|
|
||||||
gen_call_function_raw((void*)&FPU_PREP_PUSH);
|
|
||||||
gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true);
|
|
||||||
gen_restore_reg(FC_OP1);
|
|
||||||
gen_call_function_RR((void*)&FPU_FST,FC_OP1,FC_OP2);
|
|
||||||
break;
|
|
||||||
case 0x01: /* FXCH STi */
|
|
||||||
dyn_fpu_top();
|
|
||||||
gen_call_function_RR((void*)&FPU_FXCH,FC_OP1,FC_OP2);
|
|
||||||
break;
|
|
||||||
case 0x02: /* FNOP */
|
|
||||||
gen_call_function_raw((void*)&FPU_FNOP);
|
|
||||||
break;
|
|
||||||
case 0x03: /* FSTP STi */
|
|
||||||
dyn_fpu_top();
|
|
||||||
gen_call_function_RR((void*)&FPU_FST,FC_OP1,FC_OP2);
|
|
||||||
gen_call_function_raw((void*)&FPU_FPOP);
|
|
||||||
break;
|
|
||||||
case 0x04:
|
|
||||||
switch(decode.modrm.rm){
|
|
||||||
case 0x00: /* FCHS */
|
|
||||||
gen_call_function_raw((void*)&FPU_FCHS);
|
|
||||||
break;
|
|
||||||
case 0x01: /* FABS */
|
|
||||||
gen_call_function_raw((void*)&FPU_FABS);
|
|
||||||
break;
|
|
||||||
case 0x02: /* UNKNOWN */
|
|
||||||
case 0x03: /* ILLEGAL */
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",decode.modrm.reg,decode.modrm.rm);
|
|
||||||
break;
|
|
||||||
case 0x04: /* FTST */
|
|
||||||
gen_call_function_raw((void*)&FPU_FTST);
|
|
||||||
break;
|
|
||||||
case 0x05: /* FXAM */
|
|
||||||
gen_call_function_raw((void*)&FPU_FXAM);
|
|
||||||
break;
|
|
||||||
case 0x06: /* FTSTP (cyrix)*/
|
|
||||||
case 0x07: /* UNKNOWN */
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",decode.modrm.reg,decode.modrm.rm);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 0x05:
|
|
||||||
switch(decode.modrm.rm){
|
|
||||||
case 0x00: /* FLD1 */
|
|
||||||
gen_call_function_raw((void*)&FPU_FLD1);
|
|
||||||
break;
|
|
||||||
case 0x01: /* FLDL2T */
|
|
||||||
gen_call_function_raw((void*)&FPU_FLDL2T);
|
|
||||||
break;
|
|
||||||
case 0x02: /* FLDL2E */
|
|
||||||
gen_call_function_raw((void*)&FPU_FLDL2E);
|
|
||||||
break;
|
|
||||||
case 0x03: /* FLDPI */
|
|
||||||
gen_call_function_raw((void*)&FPU_FLDPI);
|
|
||||||
break;
|
|
||||||
case 0x04: /* FLDLG2 */
|
|
||||||
gen_call_function_raw((void*)&FPU_FLDLG2);
|
|
||||||
break;
|
|
||||||
case 0x05: /* FLDLN2 */
|
|
||||||
gen_call_function_raw((void*)&FPU_FLDLN2);
|
|
||||||
break;
|
|
||||||
case 0x06: /* FLDZ*/
|
|
||||||
gen_call_function_raw((void*)&FPU_FLDZ);
|
|
||||||
break;
|
|
||||||
case 0x07: /* ILLEGAL */
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",decode.modrm.reg,decode.modrm.rm);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 0x06:
|
|
||||||
switch(decode.modrm.rm){
|
|
||||||
case 0x00: /* F2XM1 */
|
|
||||||
gen_call_function_raw((void*)&FPU_F2XM1);
|
|
||||||
break;
|
|
||||||
case 0x01: /* FYL2X */
|
|
||||||
gen_call_function_raw((void*)&FPU_FYL2X);
|
|
||||||
break;
|
|
||||||
case 0x02: /* FPTAN */
|
|
||||||
gen_call_function_raw((void*)&FPU_FPTAN);
|
|
||||||
break;
|
|
||||||
case 0x03: /* FPATAN */
|
|
||||||
gen_call_function_raw((void*)&FPU_FPATAN);
|
|
||||||
break;
|
|
||||||
case 0x04: /* FXTRACT */
|
|
||||||
gen_call_function_raw((void*)&FPU_FXTRACT);
|
|
||||||
break;
|
|
||||||
case 0x05: /* FPREM1 */
|
|
||||||
gen_call_function_raw((void*)&FPU_FPREM1);
|
|
||||||
break;
|
|
||||||
case 0x06: /* FDECSTP */
|
|
||||||
gen_call_function_raw((void*)&FPU_FDECSTP);
|
|
||||||
break;
|
|
||||||
case 0x07: /* FINCSTP */
|
|
||||||
gen_call_function_raw((void*)&FPU_FINCSTP);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",decode.modrm.reg,decode.modrm.rm);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 0x07:
|
|
||||||
switch(decode.modrm.rm){
|
|
||||||
case 0x00: /* FPREM */
|
|
||||||
gen_call_function_raw((void*)&FPU_FPREM);
|
|
||||||
break;
|
|
||||||
case 0x01: /* FYL2XP1 */
|
|
||||||
gen_call_function_raw((void*)&FPU_FYL2XP1);
|
|
||||||
break;
|
|
||||||
case 0x02: /* FSQRT */
|
|
||||||
gen_call_function_raw((void*)&FPU_FSQRT);
|
|
||||||
break;
|
|
||||||
case 0x03: /* FSINCOS */
|
|
||||||
gen_call_function_raw((void*)&FPU_FSINCOS);
|
|
||||||
break;
|
|
||||||
case 0x04: /* FRNDINT */
|
|
||||||
gen_call_function_raw((void*)&FPU_FRNDINT);
|
|
||||||
break;
|
|
||||||
case 0x05: /* FSCALE */
|
|
||||||
gen_call_function_raw((void*)&FPU_FSCALE);
|
|
||||||
break;
|
|
||||||
case 0x06: /* FSIN */
|
|
||||||
gen_call_function_raw((void*)&FPU_FSIN);
|
|
||||||
break;
|
|
||||||
case 0x07: /* FCOS */
|
|
||||||
gen_call_function_raw((void*)&FPU_FCOS);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",decode.modrm.reg,decode.modrm.rm);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 1:Unhandled group %X subfunction %X",decode.modrm.reg,decode.modrm.rm);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
switch(decode.modrm.reg){
|
|
||||||
case 0x00: /* FLD float*/
|
|
||||||
gen_call_function_raw((void*)&FPU_PREP_PUSH);
|
|
||||||
dyn_fill_ea(FC_OP1);
|
|
||||||
gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true);
|
|
||||||
gen_call_function_RR((void*)&FPU_FLD_F32,FC_OP1,FC_OP2);
|
|
||||||
break;
|
|
||||||
case 0x01: /* UNKNOWN */
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC EA 1:Unhandled group %d subfunction %d",decode.modrm.reg,decode.modrm.rm);
|
|
||||||
break;
|
|
||||||
case 0x02: /* FST float*/
|
|
||||||
dyn_fill_ea(FC_ADDR);
|
|
||||||
gen_call_function_R((void*)&FPU_FST_F32,FC_ADDR);
|
|
||||||
break;
|
|
||||||
case 0x03: /* FSTP float*/
|
|
||||||
dyn_fill_ea(FC_ADDR);
|
|
||||||
gen_call_function_R((void*)&FPU_FST_F32,FC_ADDR);
|
|
||||||
gen_call_function_raw((void*)&FPU_FPOP);
|
|
||||||
break;
|
|
||||||
case 0x04: /* FLDENV */
|
|
||||||
dyn_fill_ea(FC_ADDR);
|
|
||||||
gen_call_function_R((void*)&FPU_FLDENV,FC_ADDR);
|
|
||||||
break;
|
|
||||||
case 0x05: /* FLDCW */
|
|
||||||
dyn_fill_ea(FC_ADDR);
|
|
||||||
gen_call_function_R((void *)&FPU_FLDCW,FC_ADDR);
|
|
||||||
break;
|
|
||||||
case 0x06: /* FSTENV */
|
|
||||||
dyn_fill_ea(FC_ADDR);
|
|
||||||
gen_call_function_R((void *)&FPU_FSTENV,FC_ADDR);
|
|
||||||
break;
|
|
||||||
case 0x07: /* FNSTCW*/
|
|
||||||
dyn_fill_ea(FC_ADDR);
|
|
||||||
gen_call_function_R((void *)&FPU_FNSTCW,FC_ADDR);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC EA 1:Unhandled group %d subfunction %d",decode.modrm.reg,decode.modrm.rm);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dyn_fpu_esc2(){
|
|
||||||
dyn_get_modrm();
|
|
||||||
if (decode.modrm.val >= 0xc0) {
|
|
||||||
switch(decode.modrm.reg){
|
|
||||||
case 0x05:
|
|
||||||
switch(decode.modrm.rm){
|
|
||||||
case 0x01: /* FUCOMPP */
|
|
||||||
gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true);
|
|
||||||
gen_add_imm(FC_OP2,1);
|
|
||||||
gen_and_imm(FC_OP2,7);
|
|
||||||
gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true);
|
|
||||||
gen_call_function_RR((void *)&FPU_FUCOM,FC_OP1,FC_OP2);
|
|
||||||
gen_call_function_raw((void *)&FPU_FPOP);
|
|
||||||
gen_call_function_raw((void *)&FPU_FPOP);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 2:Unhandled group %d subfunction %d",decode.modrm.reg,decode.modrm.rm);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 2:Unhandled group %d subfunction %d",decode.modrm.reg,decode.modrm.rm);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dyn_fill_ea(FC_ADDR);
|
|
||||||
gen_call_function_R((void*)&FPU_FLD_I32_EA,FC_ADDR);
|
|
||||||
gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true);
|
|
||||||
dyn_eatree();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dyn_fpu_esc3(){
|
|
||||||
dyn_get_modrm();
|
|
||||||
if (decode.modrm.val >= 0xc0) {
|
|
||||||
switch (decode.modrm.reg) {
|
|
||||||
case 0x04:
|
|
||||||
switch (decode.modrm.rm) {
|
|
||||||
case 0x00: //FNENI
|
|
||||||
case 0x01: //FNDIS
|
|
||||||
LOG(LOG_FPU,LOG_ERROR)("8087 only fpu code used esc 3: group 4: subfuntion: %d",decode.modrm.rm);
|
|
||||||
break;
|
|
||||||
case 0x02: //FNCLEX FCLEX
|
|
||||||
gen_call_function_raw((void*)&FPU_FCLEX);
|
|
||||||
break;
|
|
||||||
case 0x03: //FNINIT FINIT
|
|
||||||
gen_call_function_raw((void*)&FPU_FINIT);
|
|
||||||
break;
|
|
||||||
case 0x04: //FNSETPM
|
|
||||||
case 0x05: //FRSTPM
|
|
||||||
// LOG(LOG_FPU,LOG_ERROR)("80267 protected mode (un)set. Nothing done");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
E_Exit("ESC 3:ILLEGAL OPCODE group %d subfunction %d",decode.modrm.reg,decode.modrm.rm);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 3:Unhandled group %d subfunction %d",decode.modrm.reg,decode.modrm.rm);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
switch(decode.modrm.reg){
|
|
||||||
case 0x00: /* FILD */
|
|
||||||
gen_call_function_raw((void*)&FPU_PREP_PUSH);
|
|
||||||
dyn_fill_ea(FC_OP1);
|
|
||||||
gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true);
|
|
||||||
gen_call_function_RR((void*)&FPU_FLD_I32,FC_OP1,FC_OP2);
|
|
||||||
break;
|
|
||||||
case 0x01: /* FISTTP */
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 3 EA:Unhandled group %d subfunction %d",decode.modrm.reg,decode.modrm.rm);
|
|
||||||
break;
|
|
||||||
case 0x02: /* FIST */
|
|
||||||
dyn_fill_ea(FC_ADDR);
|
|
||||||
gen_call_function_R((void*)&FPU_FST_I32,FC_ADDR);
|
|
||||||
break;
|
|
||||||
case 0x03: /* FISTP */
|
|
||||||
dyn_fill_ea(FC_ADDR);
|
|
||||||
gen_call_function_R((void*)&FPU_FST_I32,FC_ADDR);
|
|
||||||
gen_call_function_raw((void*)&FPU_FPOP);
|
|
||||||
break;
|
|
||||||
case 0x05: /* FLD 80 Bits Real */
|
|
||||||
gen_call_function_raw((void*)&FPU_PREP_PUSH);
|
|
||||||
dyn_fill_ea(FC_ADDR);
|
|
||||||
gen_call_function_R((void*)&FPU_FLD_F80,FC_ADDR);
|
|
||||||
break;
|
|
||||||
case 0x07: /* FSTP 80 Bits Real */
|
|
||||||
dyn_fill_ea(FC_ADDR);
|
|
||||||
gen_call_function_R((void*)&FPU_FST_F80,FC_ADDR);
|
|
||||||
gen_call_function_raw((void*)&FPU_FPOP);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 3 EA:Unhandled group %d subfunction %d",decode.modrm.reg,decode.modrm.rm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dyn_fpu_esc4(){
|
|
||||||
dyn_get_modrm();
|
|
||||||
if (decode.modrm.val >= 0xc0) {
|
|
||||||
switch(decode.modrm.reg){
|
|
||||||
case 0x00: /* FADD STi,ST*/
|
|
||||||
dyn_fpu_top_swapped();
|
|
||||||
gen_call_function_RR((void*)&FPU_FADD,FC_OP1,FC_OP2);
|
|
||||||
break;
|
|
||||||
case 0x01: /* FMUL STi,ST*/
|
|
||||||
dyn_fpu_top_swapped();
|
|
||||||
gen_call_function_RR((void*)&FPU_FMUL,FC_OP1,FC_OP2);
|
|
||||||
break;
|
|
||||||
case 0x02: /* FCOM*/
|
|
||||||
dyn_fpu_top();
|
|
||||||
gen_call_function_RR((void*)&FPU_FCOM,FC_OP1,FC_OP2);
|
|
||||||
break;
|
|
||||||
case 0x03: /* FCOMP*/
|
|
||||||
dyn_fpu_top();
|
|
||||||
gen_call_function_RR((void*)&FPU_FCOM,FC_OP1,FC_OP2);
|
|
||||||
gen_call_function_raw((void*)&FPU_FPOP);
|
|
||||||
break;
|
|
||||||
case 0x04: /* FSUBR STi,ST*/
|
|
||||||
dyn_fpu_top_swapped();
|
|
||||||
gen_call_function_RR((void*)&FPU_FSUBR,FC_OP1,FC_OP2);
|
|
||||||
break;
|
|
||||||
case 0x05: /* FSUB STi,ST*/
|
|
||||||
dyn_fpu_top_swapped();
|
|
||||||
gen_call_function_RR((void*)&FPU_FSUB,FC_OP1,FC_OP2);
|
|
||||||
break;
|
|
||||||
case 0x06: /* FDIVR STi,ST*/
|
|
||||||
dyn_fpu_top_swapped();
|
|
||||||
gen_call_function_RR((void*)&FPU_FDIVR,FC_OP1,FC_OP2);
|
|
||||||
break;
|
|
||||||
case 0x07: /* FDIV STi,ST*/
|
|
||||||
dyn_fpu_top_swapped();
|
|
||||||
gen_call_function_RR((void*)&FPU_FDIV,FC_OP1,FC_OP2);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dyn_fill_ea(FC_ADDR);
|
|
||||||
gen_call_function_R((void*)&FPU_FLD_F64_EA,FC_ADDR);
|
|
||||||
gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true);
|
|
||||||
dyn_eatree();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dyn_fpu_esc5(){
|
|
||||||
dyn_get_modrm();
|
|
||||||
if (decode.modrm.val >= 0xc0) {
|
|
||||||
dyn_fpu_top();
|
|
||||||
switch(decode.modrm.reg){
|
|
||||||
case 0x00: /* FFREE STi */
|
|
||||||
gen_call_function_R((void*)&FPU_FFREE,FC_OP2);
|
|
||||||
break;
|
|
||||||
case 0x01: /* FXCH STi*/
|
|
||||||
gen_call_function_RR((void*)&FPU_FXCH,FC_OP1,FC_OP2);
|
|
||||||
break;
|
|
||||||
case 0x02: /* FST STi */
|
|
||||||
gen_call_function_RR((void*)&FPU_FST,FC_OP1,FC_OP2);
|
|
||||||
break;
|
|
||||||
case 0x03: /* FSTP STi*/
|
|
||||||
gen_call_function_RR((void*)&FPU_FST,FC_OP1,FC_OP2);
|
|
||||||
gen_call_function_raw((void*)&FPU_FPOP);
|
|
||||||
break;
|
|
||||||
case 0x04: /* FUCOM STi */
|
|
||||||
gen_call_function_RR((void*)&FPU_FUCOM,FC_OP1,FC_OP2);
|
|
||||||
break;
|
|
||||||
case 0x05: /*FUCOMP STi */
|
|
||||||
gen_call_function_RR((void*)&FPU_FUCOM,FC_OP1,FC_OP2);
|
|
||||||
gen_call_function_raw((void*)&FPU_FPOP);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 5:Unhandled group %d subfunction %d",decode.modrm.reg,decode.modrm.rm);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
switch(decode.modrm.reg){
|
|
||||||
case 0x00: /* FLD double real*/
|
|
||||||
gen_call_function_raw((void*)&FPU_PREP_PUSH);
|
|
||||||
dyn_fill_ea(FC_OP1);
|
|
||||||
gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true);
|
|
||||||
gen_call_function_RR((void*)&FPU_FLD_F64,FC_OP1,FC_OP2);
|
|
||||||
break;
|
|
||||||
case 0x01: /* FISTTP longint*/
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 5 EA:Unhandled group %d subfunction %d",decode.modrm.reg,decode.modrm.rm);
|
|
||||||
break;
|
|
||||||
case 0x02: /* FST double real*/
|
|
||||||
dyn_fill_ea(FC_ADDR);
|
|
||||||
gen_call_function_R((void*)&FPU_FST_F64,FC_ADDR);
|
|
||||||
break;
|
|
||||||
case 0x03: /* FSTP double real*/
|
|
||||||
dyn_fill_ea(FC_ADDR);
|
|
||||||
gen_call_function_R((void*)&FPU_FST_F64,FC_ADDR);
|
|
||||||
gen_call_function_raw((void*)&FPU_FPOP);
|
|
||||||
break;
|
|
||||||
case 0x04: /* FRSTOR */
|
|
||||||
dyn_fill_ea(FC_ADDR);
|
|
||||||
gen_call_function_R((void*)&FPU_FRSTOR,FC_ADDR);
|
|
||||||
break;
|
|
||||||
case 0x06: /* FSAVE */
|
|
||||||
dyn_fill_ea(FC_ADDR);
|
|
||||||
gen_call_function_R((void*)&FPU_FSAVE,FC_ADDR);
|
|
||||||
break;
|
|
||||||
case 0x07: /*FNSTSW */
|
|
||||||
gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true);
|
|
||||||
gen_call_function_R((void*)&FPU_SET_TOP,FC_OP1);
|
|
||||||
dyn_fill_ea(FC_OP1);
|
|
||||||
gen_mov_word_to_reg(FC_OP2,(void*)(&fpu.sw),true);
|
|
||||||
gen_call_function_RR((void*)&mem_writew,FC_OP1,FC_OP2);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 5 EA:Unhandled group %d subfunction %d",decode.modrm.reg,decode.modrm.rm);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dyn_fpu_esc6(){
|
|
||||||
dyn_get_modrm();
|
|
||||||
if (decode.modrm.val >= 0xc0) {
|
|
||||||
switch(decode.modrm.reg){
|
|
||||||
case 0x00: /*FADDP STi,ST*/
|
|
||||||
dyn_fpu_top_swapped();
|
|
||||||
gen_call_function_RR((void*)&FPU_FADD,FC_OP1,FC_OP2);
|
|
||||||
break;
|
|
||||||
case 0x01: /* FMULP STi,ST*/
|
|
||||||
dyn_fpu_top_swapped();
|
|
||||||
gen_call_function_RR((void*)&FPU_FMUL,FC_OP1,FC_OP2);
|
|
||||||
break;
|
|
||||||
case 0x02: /* FCOMP5*/
|
|
||||||
dyn_fpu_top();
|
|
||||||
gen_call_function_RR((void*)&FPU_FCOM,FC_OP1,FC_OP2);
|
|
||||||
break; /* TODO IS THIS ALLRIGHT ????????? */
|
|
||||||
case 0x03: /*FCOMPP*/
|
|
||||||
if(decode.modrm.rm != 1) {
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 6:Unhandled group %d subfunction %d",decode.modrm.reg,decode.modrm.rm);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true);
|
|
||||||
gen_add_imm(FC_OP2,1);
|
|
||||||
gen_and_imm(FC_OP2,7);
|
|
||||||
gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true);
|
|
||||||
gen_call_function_RR((void*)&FPU_FCOM,FC_OP1,FC_OP2);
|
|
||||||
gen_call_function_raw((void*)&FPU_FPOP); /* extra pop at the bottom*/
|
|
||||||
break;
|
|
||||||
case 0x04: /* FSUBRP STi,ST*/
|
|
||||||
dyn_fpu_top_swapped();
|
|
||||||
gen_call_function_RR((void*)&FPU_FSUBR,FC_OP1,FC_OP2);
|
|
||||||
break;
|
|
||||||
case 0x05: /* FSUBP STi,ST*/
|
|
||||||
dyn_fpu_top_swapped();
|
|
||||||
gen_call_function_RR((void*)&FPU_FSUB,FC_OP1,FC_OP2);
|
|
||||||
break;
|
|
||||||
case 0x06: /* FDIVRP STi,ST*/
|
|
||||||
dyn_fpu_top_swapped();
|
|
||||||
gen_call_function_RR((void*)&FPU_FDIVR,FC_OP1,FC_OP2);
|
|
||||||
break;
|
|
||||||
case 0x07: /* FDIVP STi,ST*/
|
|
||||||
dyn_fpu_top_swapped();
|
|
||||||
gen_call_function_RR((void*)&FPU_FDIV,FC_OP1,FC_OP2);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
gen_call_function_raw((void*)&FPU_FPOP);
|
|
||||||
} else {
|
|
||||||
dyn_fill_ea(FC_ADDR);
|
|
||||||
gen_call_function_R((void*)&FPU_FLD_I16_EA,FC_ADDR);
|
|
||||||
gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true);
|
|
||||||
dyn_eatree();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dyn_fpu_esc7(){
|
|
||||||
dyn_get_modrm();
|
|
||||||
if (decode.modrm.val >= 0xc0) {
|
|
||||||
switch (decode.modrm.reg){
|
|
||||||
case 0x01: /* FXCH STi*/
|
|
||||||
dyn_fpu_top();
|
|
||||||
gen_call_function_RR((void*)&FPU_FXCH,FC_OP1,FC_OP2);
|
|
||||||
break;
|
|
||||||
case 0x02: /* FSTP STi*/
|
|
||||||
case 0x03: /* FSTP STi*/
|
|
||||||
dyn_fpu_top();
|
|
||||||
gen_call_function_RR((void*)&FPU_FST,FC_OP1,FC_OP2);
|
|
||||||
gen_call_function_raw((void*)&FPU_FPOP);
|
|
||||||
break;
|
|
||||||
case 0x04:
|
|
||||||
switch(decode.modrm.rm){
|
|
||||||
case 0x00: /* FNSTSW AX*/
|
|
||||||
gen_mov_word_to_reg(FC_OP1,(void*)(&TOP),true);
|
|
||||||
gen_call_function_R((void*)&FPU_SET_TOP,FC_OP1);
|
|
||||||
gen_mov_word_to_reg(FC_OP1,(void*)(&fpu.sw),false);
|
|
||||||
MOV_REG_WORD16_FROM_HOST_REG(FC_OP1,DRC_REG_EAX);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",decode.modrm.reg,decode.modrm.rm);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 7:Unhandled group %d subfunction %d",decode.modrm.reg,decode.modrm.rm);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
switch(decode.modrm.reg){
|
|
||||||
case 0x00: /* FILD Bit16s */
|
|
||||||
gen_call_function_raw((void*)&FPU_PREP_PUSH);
|
|
||||||
dyn_fill_ea(FC_OP1);
|
|
||||||
gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true);
|
|
||||||
gen_call_function_RR((void*)&FPU_FLD_I16,FC_OP1,FC_OP2);
|
|
||||||
break;
|
|
||||||
case 0x01:
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 7 EA:Unhandled group %d subfunction %d",decode.modrm.reg,decode.modrm.rm);
|
|
||||||
break;
|
|
||||||
case 0x02: /* FIST Bit16s */
|
|
||||||
dyn_fill_ea(FC_ADDR);
|
|
||||||
gen_call_function_R((void*)&FPU_FST_I16,FC_ADDR);
|
|
||||||
break;
|
|
||||||
case 0x03: /* FISTP Bit16s */
|
|
||||||
dyn_fill_ea(FC_ADDR);
|
|
||||||
gen_call_function_R((void*)&FPU_FST_I16,FC_ADDR);
|
|
||||||
gen_call_function_raw((void*)&FPU_FPOP);
|
|
||||||
break;
|
|
||||||
case 0x04: /* FBLD packed BCD */
|
|
||||||
gen_call_function_raw((void*)&FPU_PREP_PUSH);
|
|
||||||
dyn_fill_ea(FC_OP1);
|
|
||||||
gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true);
|
|
||||||
gen_call_function_RR((void*)&FPU_FBLD,FC_OP1,FC_OP2);
|
|
||||||
break;
|
|
||||||
case 0x05: /* FILD Bit64s */
|
|
||||||
gen_call_function_raw((void*)&FPU_PREP_PUSH);
|
|
||||||
dyn_fill_ea(FC_OP1);
|
|
||||||
gen_mov_word_to_reg(FC_OP2,(void*)(&TOP),true);
|
|
||||||
gen_call_function_RR((void*)&FPU_FLD_I64,FC_OP1,FC_OP2);
|
|
||||||
break;
|
|
||||||
case 0x06: /* FBSTP packed BCD */
|
|
||||||
dyn_fill_ea(FC_ADDR);
|
|
||||||
gen_call_function_R((void*)&FPU_FBST,FC_ADDR);
|
|
||||||
gen_call_function_raw((void*)&FPU_FPOP);
|
|
||||||
break;
|
|
||||||
case 0x07: /* FISTP Bit64s */
|
|
||||||
dyn_fill_ea(FC_ADDR);
|
|
||||||
gen_call_function_R((void*)&FPU_FST_I64,FC_ADDR);
|
|
||||||
gen_call_function_raw((void*)&FPU_FPOP);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(LOG_FPU,LOG_WARN)("ESC 7 EA:Unhandled group %d subfunction %d",decode.modrm.reg,decode.modrm.rm);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user